1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package javax.swing;
27
28 import java.awt.*;
29 import java.awt.event.*;
30 import java.beans.*;
31 import java.io.*;
32 import java.util.*;
33 import javax.swing.event.*;
34 import javax.swing.plaf.*;
35 import javax.swing.tree.*;
36 import javax.swing.text.Position;
37 import javax.accessibility.*;
38 import sun.swing.SwingUtilities2;
39 import sun.swing.SwingUtilities2.Section;
40 import static sun.swing.SwingUtilities2.Section.*;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 public class JTree extends JComponent implements Scrollable, Accessible
146 {
147
148
149
150
151 private static final String uiClassID = "TreeUI";
152
153
154
155
156 transient protected TreeModel treeModel;
157
158
159
160
161 transient protected TreeSelectionModel selectionModel;
162
163
164
165
166
167 protected boolean rootVisible;
168
169
170
171
172
173 transient protected TreeCellRenderer cellRenderer;
174
175
176
177
178
179 protected int rowHeight;
180 private boolean rowHeightSet = false;
181
182
183
184
185
186
187
188
189
190 transient private Hashtable<TreePath, Boolean> expandedState;
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215 protected boolean showsRootHandles;
216 private boolean showsRootHandlesSet = false;
217
218
219
220
221
222 protected transient TreeSelectionRedirector selectionRedirector;
223
224
225
226
227
228 transient protected TreeCellEditor cellEditor;
229
230
231
232
233 protected boolean editable;
234
235
236
237
238
239
240
241
242
243
244
245 protected boolean largeModel;
246
247
248
249
250
251
252 protected int visibleRowCount;
253
254
255
256
257
258
259
260
261 protected boolean invokesStopCellEditing;
262
263
264
265
266
267 protected boolean scrollsOnExpand;
268 private boolean scrollsOnExpandSet = false;
269
270
271
272
273 protected int toggleClickCount;
274
275
276
277
278 transient protected TreeModelListener treeModelListener;
279
280
281
282
283
284 transient private Stack<Stack<TreePath>> expandedStack;
285
286
287
288
289 private TreePath leadPath;
290
291
292
293
294 private TreePath anchorPath;
295
296
297
298
299 private boolean expandsSelectedPaths;
300
301
302
303
304 private boolean settingUI;
305
306
307 private boolean dragEnabled;
308
309
310
311
312 private DropMode dropMode = DropMode.USE_SELECTION;
313
314
315
316
317 private transient DropLocation dropLocation;
318
319
320
321
322
323
324
325
326 public static final class DropLocation extends TransferHandler.DropLocation {
327 private final TreePath path;
328 private final int index;
329
330 private DropLocation(Point p, TreePath path, int index) {
331 super(p);
332 this.path = path;
333 this.index = index;
334 }
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 public int getChildIndex() {
361 return index;
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399 public TreePath getPath() {
400 return path;
401 }
402
403
404
405
406
407
408
409
410
411 public String toString() {
412 return getClass().getName()
413 + "[dropPoint=" + getDropPoint() + ","
414 + "path=" + path + ","
415 + "childIndex=" + index + "]";
416 }
417 }
418
419
420
421
422 private int expandRow = -1;
423
424 private class TreeTimer extends Timer {
425 public TreeTimer() {
426 super(2000, null);
427 setRepeats(false);
428 }
429
430 public void fireActionPerformed(ActionEvent ae) {
431 JTree.this.expandRow(expandRow);
432 }
433 }
434
435
436
437
438 private TreeTimer dropTimer;
439
440
441
442
443
444
445
446
447
448 private transient TreeExpansionListener uiTreeExpansionListener;
449
450
451
452
453 private static int TEMP_STACK_SIZE = 11;
454
455
456
457
458
459 public final static String CELL_RENDERER_PROPERTY = "cellRenderer";
460
461 public final static String TREE_MODEL_PROPERTY = "model";
462
463 public final static String ROOT_VISIBLE_PROPERTY = "rootVisible";
464
465 public final static String SHOWS_ROOT_HANDLES_PROPERTY = "showsRootHandles";
466
467 public final static String ROW_HEIGHT_PROPERTY = "rowHeight";
468
469 public final static String CELL_EDITOR_PROPERTY = "cellEditor";
470
471 public final static String EDITABLE_PROPERTY = "editable";
472
473 public final static String LARGE_MODEL_PROPERTY = "largeModel";
474
475 public final static String SELECTION_MODEL_PROPERTY = "selectionModel";
476
477 public final static String VISIBLE_ROW_COUNT_PROPERTY = "visibleRowCount";
478
479 public final static String INVOKES_STOP_CELL_EDITING_PROPERTY = "invokesStopCellEditing";
480
481 public final static String SCROLLS_ON_EXPAND_PROPERTY = "scrollsOnExpand";
482
483 public final static String TOGGLE_CLICK_COUNT_PROPERTY = "toggleClickCount";
484
485
486 public final static String LEAD_SELECTION_PATH_PROPERTY = "leadSelectionPath";
487
488
489 public final static String ANCHOR_SELECTION_PATH_PROPERTY = "anchorSelectionPath";
490
491
492 public final static String EXPANDS_SELECTED_PATHS_PROPERTY = "expandsSelectedPaths";
493
494
495
496
497
498
499
500
501 protected static TreeModel getDefaultTreeModel() {
502 DefaultMutableTreeNode root = new DefaultMutableTreeNode("JTree");
503 DefaultMutableTreeNode parent;
504
505 parent = new DefaultMutableTreeNode("colors");
506 root.add(parent);
507 parent.add(new DefaultMutableTreeNode("blue"));
508 parent.add(new DefaultMutableTreeNode("violet"));
509 parent.add(new DefaultMutableTreeNode("red"));
510 parent.add(new DefaultMutableTreeNode("yellow"));
511
512 parent = new DefaultMutableTreeNode("sports");
513 root.add(parent);
514 parent.add(new DefaultMutableTreeNode("basketball"));
515 parent.add(new DefaultMutableTreeNode("soccer"));
516 parent.add(new DefaultMutableTreeNode("football"));
517 parent.add(new DefaultMutableTreeNode("hockey"));
518
519 parent = new DefaultMutableTreeNode("food");
520 root.add(parent);
521 parent.add(new DefaultMutableTreeNode("hot dogs"));
522 parent.add(new DefaultMutableTreeNode("pizza"));
523 parent.add(new DefaultMutableTreeNode("ravioli"));
524 parent.add(new DefaultMutableTreeNode("bananas"));
525 return new DefaultTreeModel(root);
526 }
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542 protected static TreeModel createTreeModel(Object value) {
543 DefaultMutableTreeNode root;
544
545 if((value instanceof Object[]) || (value instanceof Hashtable) ||
546 (value instanceof Vector)) {
547 root = new DefaultMutableTreeNode("root");
548 DynamicUtilTreeNode.createChildren(root, value);
549 }
550 else {
551 root = new DynamicUtilTreeNode("root", value);
552 }
553 return new DefaultTreeModel(root, false);
554 }
555
556
557
558
559
560
561
562
563 public JTree() {
564 this(getDefaultTreeModel());
565 }
566
567
568
569
570
571
572
573
574
575
576
577 public JTree(Object[] value) {
578 this(createTreeModel(value));
579 this.setRootVisible(false);
580 this.setShowsRootHandles(true);
581 expandRoot();
582 }
583
584
585
586
587
588
589
590
591
592
593 public JTree(Vector<?> value) {
594 this(createTreeModel(value));
595 this.setRootVisible(false);
596 this.setShowsRootHandles(true);
597 expandRoot();
598 }
599
600
601
602
603
604
605
606
607
608
609
610 public JTree(Hashtable<?,?> value) {
611 this(createTreeModel(value));
612 this.setRootVisible(false);
613 this.setShowsRootHandles(true);
614 expandRoot();
615 }
616
617
618
619
620
621
622
623
624
625
626 public JTree(TreeNode root) {
627 this(root, false);
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642 public JTree(TreeNode root, boolean asksAllowsChildren) {
643 this(new DefaultTreeModel(root, asksAllowsChildren));
644 }
645
646
647
648
649
650
651
652 @ConstructorProperties({"model"})
653 public JTree(TreeModel newModel) {
654 super();
655 expandedStack = new Stack<Stack<TreePath>>();
656 toggleClickCount = 2;
657 expandedState = new Hashtable<TreePath, Boolean>();
658 setLayout(null);
659 rowHeight = 16;
660 visibleRowCount = 20;
661 rootVisible = true;
662 selectionModel = new DefaultTreeSelectionModel();
663 cellRenderer = null;
664 scrollsOnExpand = true;
665 setOpaque(true);
666 expandsSelectedPaths = true;
667 updateUI();
668 setModel(newModel);
669 }
670
671
672
673
674
675
676 public TreeUI getUI() {
677 return (TreeUI)ui;
678 }
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693 public void setUI(TreeUI ui) {
694 if (this.ui != ui) {
695 settingUI = true;
696 uiTreeExpansionListener = null;
697 try {
698 super.setUI(ui);
699 }
700 finally {
701 settingUI = false;
702 }
703 }
704 }
705
706
707
708
709
710
711
712
713 public void updateUI() {
714 setUI((TreeUI)UIManager.getUI(this));
715
716 SwingUtilities.updateRendererOrEditorUI(getCellRenderer());
717 SwingUtilities.updateRendererOrEditorUI(getCellEditor());
718 }
719
720
721
722
723
724
725
726
727
728 public String getUIClassID() {
729 return uiClassID;
730 }
731
732
733
734
735
736
737
738
739 public TreeCellRenderer getCellRenderer() {
740 return cellRenderer;
741 }
742
743
744
745
746
747
748
749
750
751
752
753
754
755 public void setCellRenderer(TreeCellRenderer x) {
756 TreeCellRenderer oldValue = cellRenderer;
757
758 cellRenderer = x;
759 firePropertyChange(CELL_RENDERER_PROPERTY, oldValue, cellRenderer);
760 invalidate();
761 }
762
763
764
765
766
767
768
769
770
771
772
773
774
775 public void setEditable(boolean flag) {
776 boolean oldValue = this.editable;
777
778 this.editable = flag;
779 firePropertyChange(EDITABLE_PROPERTY, oldValue, flag);
780 if (accessibleContext != null) {
781 accessibleContext.firePropertyChange(
782 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
783 (oldValue ? AccessibleState.EDITABLE : null),
784 (flag ? AccessibleState.EDITABLE : null));
785 }
786 }
787
788
789
790
791
792
793 public boolean isEditable() {
794 return editable;
795 }
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811 public void setCellEditor(TreeCellEditor cellEditor) {
812 TreeCellEditor oldEditor = this.cellEditor;
813
814 this.cellEditor = cellEditor;
815 firePropertyChange(CELL_EDITOR_PROPERTY, oldEditor, cellEditor);
816 invalidate();
817 }
818
819
820
821
822
823
824
825 public TreeCellEditor getCellEditor() {
826 return cellEditor;
827 }
828
829
830
831
832
833
834 public TreeModel getModel() {
835 return treeModel;
836 }
837
838
839
840
841
842
843
844
845
846
847
848 public void setModel(TreeModel newModel) {
849 clearSelection();
850
851 TreeModel oldModel = treeModel;
852
853 if(treeModel != null && treeModelListener != null)
854 treeModel.removeTreeModelListener(treeModelListener);
855
856 if (accessibleContext != null) {
857 if (treeModel != null) {
858 treeModel.removeTreeModelListener((TreeModelListener)accessibleContext);
859 }
860 if (newModel != null) {
861 newModel.addTreeModelListener((TreeModelListener)accessibleContext);
862 }
863 }
864
865 treeModel = newModel;
866 clearToggledPaths();
867 if(treeModel != null) {
868 if(treeModelListener == null)
869 treeModelListener = createTreeModelListener();
870 if(treeModelListener != null)
871 treeModel.addTreeModelListener(treeModelListener);
872
873 if(treeModel.getRoot() != null &&
874 !treeModel.isLeaf(treeModel.getRoot())) {
875 expandedState.put(new TreePath(treeModel.getRoot()),
876 Boolean.TRUE);
877 }
878 }
879 firePropertyChange(TREE_MODEL_PROPERTY, oldModel, treeModel);
880 invalidate();
881 }
882
883
884
885
886
887
888
889 public boolean isRootVisible() {
890 return rootVisible;
891 }
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906 public void setRootVisible(boolean rootVisible) {
907 boolean oldValue = this.rootVisible;
908
909 this.rootVisible = rootVisible;
910 firePropertyChange(ROOT_VISIBLE_PROPERTY, oldValue, this.rootVisible);
911 if (accessibleContext != null) {
912 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange();
913 }
914 }
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935 public void setShowsRootHandles(boolean newValue) {
936 boolean oldValue = showsRootHandles;
937 TreeModel model = getModel();
938
939 showsRootHandles = newValue;
940 showsRootHandlesSet = true;
941 firePropertyChange(SHOWS_ROOT_HANDLES_PROPERTY, oldValue,
942 showsRootHandles);
943 if (accessibleContext != null) {
944 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange();
945 }
946 invalidate();
947 }
948
949
950
951
952
953
954
955 public boolean getShowsRootHandles()
956 {
957 return showsRootHandles;
958 }
959
960
961
962
963
964
965
966
967
968
969
970
971
972 public void setRowHeight(int rowHeight)
973 {
974 int oldValue = this.rowHeight;
975
976 this.rowHeight = rowHeight;
977 rowHeightSet = true;
978 firePropertyChange(ROW_HEIGHT_PROPERTY, oldValue, this.rowHeight);
979 invalidate();
980 }
981
982
983
984
985
986
987
988 public int getRowHeight()
989 {
990 return rowHeight;
991 }
992
993
994
995
996
997
998 public boolean isFixedRowHeight()
999 {
1000 return (rowHeight > 0);
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 public void setLargeModel(boolean newValue) {
1018 boolean oldValue = largeModel;
1019
1020 largeModel = newValue;
1021 firePropertyChange(LARGE_MODEL_PROPERTY, oldValue, newValue);
1022 }
1023
1024
1025
1026
1027
1028
1029
1030 public boolean isLargeModel() {
1031 return largeModel;
1032 }
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051 public void setInvokesStopCellEditing(boolean newValue) {
1052 boolean oldValue = invokesStopCellEditing;
1053
1054 invokesStopCellEditing = newValue;
1055 firePropertyChange(INVOKES_STOP_CELL_EDITING_PROPERTY, oldValue,
1056 newValue);
1057 }
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 public boolean getInvokesStopCellEditing() {
1068 return invokesStopCellEditing;
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 public void setScrollsOnExpand(boolean newValue) {
1093 boolean oldValue = scrollsOnExpand;
1094
1095 scrollsOnExpand = newValue;
1096 scrollsOnExpandSet = true;
1097 firePropertyChange(SCROLLS_ON_EXPAND_PROPERTY, oldValue,
1098 newValue);
1099 }
1100
1101
1102
1103
1104
1105
1106 public boolean getScrollsOnExpand() {
1107 return scrollsOnExpand;
1108 }
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 public void setToggleClickCount(int clickCount) {
1122 int oldCount = toggleClickCount;
1123
1124 toggleClickCount = clickCount;
1125 firePropertyChange(TOGGLE_CLICK_COUNT_PROPERTY, oldCount,
1126 clickCount);
1127 }
1128
1129
1130
1131
1132
1133
1134
1135 public int getToggleClickCount() {
1136 return toggleClickCount;
1137 }
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161 public void setExpandsSelectedPaths(boolean newValue) {
1162 boolean oldValue = expandsSelectedPaths;
1163
1164 expandsSelectedPaths = newValue;
1165 firePropertyChange(EXPANDS_SELECTED_PATHS_PROPERTY, oldValue,
1166 newValue);
1167 }
1168
1169
1170
1171
1172
1173
1174
1175
1176 public boolean getExpandsSelectedPaths() {
1177 return expandsSelectedPaths;
1178 }
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213 public void setDragEnabled(boolean b) {
1214 if (b && GraphicsEnvironment.isHeadless()) {
1215 throw new HeadlessException();
1216 }
1217 dragEnabled = b;
1218 }
1219
1220
1221
1222
1223
1224
1225
1226
1227 public boolean getDragEnabled() {
1228 return dragEnabled;
1229 }
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259 public final void setDropMode(DropMode dropMode) {
1260 if (dropMode != null) {
1261 switch (dropMode) {
1262 case USE_SELECTION:
1263 case ON:
1264 case INSERT:
1265 case ON_OR_INSERT:
1266 this.dropMode = dropMode;
1267 return;
1268 }
1269 }
1270
1271 throw new IllegalArgumentException(dropMode + ": Unsupported drop mode for tree");
1272 }
1273
1274
1275
1276
1277
1278
1279
1280
1281 public final DropMode getDropMode() {
1282 return dropMode;
1283 }
1284
1285
1286
1287
1288
1289
1290
1291
1292 DropLocation dropLocationForPoint(Point p) {
1293 DropLocation location = null;
1294
1295 int row = getClosestRowForLocation(p.x, p.y);
1296 Rectangle bounds = getRowBounds(row);
1297 TreeModel model = getModel();
1298 Object root = (model == null) ? null : model.getRoot();
1299 TreePath rootPath = (root == null) ? null : new TreePath(root);
1300
1301 TreePath child;
1302 TreePath parent;
1303 boolean outside = row == -1
1304 || p.y < bounds.y
1305 || p.y >= bounds.y + bounds.height;
1306
1307 switch(dropMode) {
1308 case USE_SELECTION:
1309 case ON:
1310 if (outside) {
1311 location = new DropLocation(p, null, -1);
1312 } else {
1313 location = new DropLocation(p, getPathForRow(row), -1);
1314 }
1315
1316 break;
1317 case INSERT:
1318 case ON_OR_INSERT:
1319 if (row == -1) {
1320 if (root != null && !model.isLeaf(root) && isExpanded(rootPath)) {
1321 location = new DropLocation(p, rootPath, 0);
1322 } else {
1323 location = new DropLocation(p, null, -1);
1324 }
1325
1326 break;
1327 }
1328
1329 boolean checkOn = dropMode == DropMode.ON_OR_INSERT
1330 || !model.isLeaf(getPathForRow(row).getLastPathComponent());
1331
1332 Section section = SwingUtilities2.liesInVertical(bounds, p, checkOn);
1333 if(section == LEADING) {
1334 child = getPathForRow(row);
1335 parent = child.getParentPath();
1336 } else if (section == TRAILING) {
1337 int index = row + 1;
1338 if (index >= getRowCount()) {
1339 if (model.isLeaf(root) || !isExpanded(rootPath)) {
1340 location = new DropLocation(p, null, -1);
1341 } else {
1342 parent = rootPath;
1343 index = model.getChildCount(root);
1344 location = new DropLocation(p, parent, index);
1345 }
1346
1347 break;
1348 }
1349
1350 child = getPathForRow(index);
1351 parent = child.getParentPath();
1352 } else {
1353 assert checkOn;
1354 location = new DropLocation(p, getPathForRow(row), -1);
1355 break;
1356 }
1357
1358 if (parent != null) {
1359 location = new DropLocation(p, parent,
1360 model.getIndexOfChild(parent.getLastPathComponent(),
1361 child.getLastPathComponent()));
1362 } else if (checkOn || !model.isLeaf(root)) {
1363 location = new DropLocation(p, rootPath, -1);
1364 } else {
1365 location = new DropLocation(p, null, -1);
1366 }
1367
1368 break;
1369 default:
1370 assert false : "Unexpected drop mode";
1371 }
1372
1373 if (outside || row != expandRow) {
1374 cancelDropTimer();
1375 }
1376
1377 if (!outside && row != expandRow) {
1378 if (isCollapsed(row)) {
1379 expandRow = row;
1380 startDropTimer();
1381 }
1382 }
1383
1384 return location;
1385 }
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420 Object setDropLocation(TransferHandler.DropLocation location,
1421 Object state,
1422 boolean forDrop) {
1423
1424 Object retVal = null;
1425 DropLocation treeLocation = (DropLocation)location;
1426
1427 if (dropMode == DropMode.USE_SELECTION) {
1428 if (treeLocation == null) {
1429 if (!forDrop && state != null) {
1430 setSelectionPaths(((TreePath[][])state)[0]);
1431 setAnchorSelectionPath(((TreePath[][])state)[1][0]);
1432 setLeadSelectionPath(((TreePath[][])state)[1][1]);
1433 }
1434 } else {
1435 if (dropLocation == null) {
1436 TreePath[] paths = getSelectionPaths();
1437 if (paths == null) {
1438 paths = new TreePath[0];
1439 }
1440
1441 retVal = new TreePath[][] {paths,
1442 {getAnchorSelectionPath(), getLeadSelectionPath()}};
1443 } else {
1444 retVal = state;
1445 }
1446
1447 setSelectionPath(treeLocation.getPath());
1448 }
1449 }
1450
1451 DropLocation old = dropLocation;
1452 dropLocation = treeLocation;
1453 firePropertyChange("dropLocation", old, dropLocation);
1454
1455 return retVal;
1456 }
1457
1458
1459
1460
1461
1462 void dndDone() {
1463 cancelDropTimer();
1464 dropTimer = null;
1465 }
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485 public final DropLocation getDropLocation() {
1486 return dropLocation;
1487 }
1488
1489 private void startDropTimer() {
1490 if (dropTimer == null) {
1491 dropTimer = new TreeTimer();
1492 }
1493 dropTimer.start();
1494 }
1495
1496 private void cancelDropTimer() {
1497 if (dropTimer != null && dropTimer.isRunning()) {
1498 expandRow = -1;
1499 dropTimer.stop();
1500 }
1501 }
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512 public boolean isPathEditable(TreePath path) {
1513 return isEditable();
1514 }
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532 public String getToolTipText(MouseEvent event) {
1533 String tip = null;
1534
1535 if(event != null) {
1536 Point p = event.getPoint();
1537 int selRow = getRowForLocation(p.x, p.y);
1538 TreeCellRenderer r = getCellRenderer();
1539
1540 if(selRow != -1 && r != null) {
1541 TreePath path = getPathForRow(selRow);
1542 Object lastPath = path.getLastPathComponent();
1543 Component rComponent = r.getTreeCellRendererComponent
1544 (this, lastPath, isRowSelected(selRow),
1545 isExpanded(selRow), getModel().isLeaf(lastPath), selRow,
1546 true);
1547
1548 if(rComponent instanceof JComponent) {
1549 MouseEvent newEvent;
1550 Rectangle pathBounds = getPathBounds(path);
1551
1552 p.translate(-pathBounds.x, -pathBounds.y);
1553 newEvent = new MouseEvent(rComponent, event.getID(),
1554 event.getWhen(),
1555 event.getModifiers(),
1556 p.x, p.y,
1557 event.getXOnScreen(),
1558 event.getYOnScreen(),
1559 event.getClickCount(),
1560 event.isPopupTrigger(),
1561 MouseEvent.NOBUTTON);
1562
1563 tip = ((JComponent)rComponent).getToolTipText(newEvent);
1564 }
1565 }
1566 }
1567
1568 if (tip == null) {
1569 tip = getToolTipText();
1570 }
1571 return tip;
1572 }
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589 public String convertValueToText(Object value, boolean selected,
1590 boolean expanded, boolean leaf, int row,
1591 boolean hasFocus) {
1592 if(value != null) {
1593 String sValue = value.toString();
1594 if (sValue != null) {
1595 return sValue;
1596 }
1597 }
1598 return "";
1599 }
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614 public int getRowCount() {
1615 TreeUI tree = getUI();
1616
1617 if(tree != null)
1618 return tree.getRowCount(this);
1619 return 0;
1620 }
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630 public void setSelectionPath(TreePath path) {
1631 getSelectionModel().setSelectionPath(path);
1632 }
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643 public void setSelectionPaths(TreePath[] paths) {
1644 getSelectionModel().setSelectionPaths(paths);
1645 }
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660 public void setLeadSelectionPath(TreePath newPath) {
1661 TreePath oldValue = leadPath;
1662
1663 leadPath = newPath;
1664 firePropertyChange(LEAD_SELECTION_PATH_PROPERTY, oldValue, newPath);
1665 }
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680 public void setAnchorSelectionPath(TreePath newPath) {
1681 TreePath oldValue = anchorPath;
1682
1683 anchorPath = newPath;
1684 firePropertyChange(ANCHOR_SELECTION_PATH_PROPERTY, oldValue, newPath);
1685 }
1686
1687
1688
1689
1690
1691
1692
1693 public void setSelectionRow(int row) {
1694 int[] rows = { row };
1695
1696 setSelectionRows(rows);
1697 }
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711 public void setSelectionRows(int[] rows) {
1712 TreeUI ui = getUI();
1713
1714 if(ui != null && rows != null) {
1715 int numRows = rows.length;
1716 TreePath[] paths = new TreePath[numRows];
1717
1718 for(int counter = 0; counter < numRows; counter++) {
1719 paths[counter] = ui.getPathForRow(this, rows[counter]);
1720 }
1721 setSelectionPaths(paths);
1722 }
1723 }
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737 public void addSelectionPath(TreePath path) {
1738 getSelectionModel().addSelectionPath(path);
1739 }
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 public void addSelectionPaths(TreePath[] paths) {
1755 getSelectionModel().addSelectionPaths(paths);
1756 }
1757
1758
1759
1760
1761
1762
1763
1764 public void addSelectionRow(int row) {
1765 int[] rows = { row };
1766
1767 addSelectionRows(rows);
1768 }
1769
1770
1771
1772
1773
1774
1775
1776 public void addSelectionRows(int[] rows) {
1777 TreeUI ui = getUI();
1778
1779 if(ui != null && rows != null) {
1780 int numRows = rows.length;
1781 TreePath[] paths = new TreePath[numRows];
1782
1783 for(int counter = 0; counter < numRows; counter++)
1784 paths[counter] = ui.getPathForRow(this, rows[counter]);
1785 addSelectionPaths(paths);
1786 }
1787 }
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799 public Object getLastSelectedPathComponent() {
1800 TreePath selPath = getSelectionModel().getSelectionPath();
1801
1802 if(selPath != null)
1803 return selPath.getLastPathComponent();
1804 return null;
1805 }
1806
1807
1808
1809
1810
1811 public TreePath getLeadSelectionPath() {
1812 return leadPath;
1813 }
1814
1815
1816
1817
1818
1819
1820 public TreePath getAnchorSelectionPath() {
1821 return anchorPath;
1822 }
1823
1824
1825
1826
1827
1828
1829
1830 public TreePath getSelectionPath() {
1831 return getSelectionModel().getSelectionPath();
1832 }
1833
1834
1835
1836
1837
1838
1839
1840 public TreePath[] getSelectionPaths() {
1841 return getSelectionModel().getSelectionPaths();
1842 }
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854 public int[] getSelectionRows() {
1855 return getSelectionModel().getSelectionRows();
1856 }
1857
1858
1859
1860
1861
1862
1863 public int getSelectionCount() {
1864 return selectionModel.getSelectionCount();
1865 }
1866
1867
1868
1869
1870
1871
1872
1873 public int getMinSelectionRow() {
1874 return getSelectionModel().getMinSelectionRow();
1875 }
1876
1877
1878
1879
1880
1881
1882
1883 public int getMaxSelectionRow() {
1884 return getSelectionModel().getMaxSelectionRow();
1885 }
1886
1887
1888
1889
1890
1891
1892
1893
1894 public int getLeadSelectionRow() {
1895 TreePath leadPath = getLeadSelectionPath();
1896
1897 if (leadPath != null) {
1898 return getRowForPath(leadPath);
1899 }
1900 return -1;
1901 }
1902
1903
1904
1905
1906
1907
1908
1909 public boolean isPathSelected(TreePath path) {
1910 return getSelectionModel().isPathSelected(path);
1911 }
1912
1913
1914
1915
1916
1917
1918
1919
1920 public boolean isRowSelected(int row) {
1921 return getSelectionModel().isRowSelected(row);
1922 }
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939 public Enumeration<TreePath> getExpandedDescendants(TreePath parent) {
1940 if(!isExpanded(parent))
1941 return null;
1942
1943 Enumeration<TreePath> toggledPaths = expandedState.keys();
1944 Vector<TreePath> elements = null;
1945 TreePath path;
1946 Object value;
1947
1948 if(toggledPaths != null) {
1949 while(toggledPaths.hasMoreElements()) {
1950 path = toggledPaths.nextElement();
1951 value = expandedState.get(path);
1952
1953
1954
1955 if(path != parent && value != null &&
1956 ((Boolean)value).booleanValue() &&
1957 parent.isDescendant(path) && isVisible(path)) {
1958 if (elements == null) {
1959 elements = new Vector<TreePath>();
1960 }
1961 elements.addElement(path);
1962 }
1963 }
1964 }
1965 if (elements == null) {
1966 Set<TreePath> empty = Collections.emptySet();
1967 return Collections.enumeration(empty);
1968 }
1969 return elements.elements();
1970 }
1971
1972
1973
1974
1975
1976
1977 public boolean hasBeenExpanded(TreePath path) {
1978 return (path != null && expandedState.get(path) != null);
1979 }
1980
1981
1982
1983
1984
1985
1986
1987
1988 public boolean isExpanded(TreePath path) {
1989
1990 if(path == null)
1991 return false;
1992 Object value;
1993
1994 do{
1995 value = expandedState.get(path);
1996 if(value == null || !((Boolean)value).booleanValue())
1997 return false;
1998 } while( (path=path.getParentPath())!=null );
1999
2000 return true;
2001 }
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011 public boolean isExpanded(int row) {
2012 TreeUI tree = getUI();
2013
2014 if(tree != null) {
2015 TreePath path = tree.getPathForRow(this, row);
2016
2017 if(path != null) {
2018 Boolean value = expandedState.get(path);
2019
2020 return (value != null && value.booleanValue());
2021 }
2022 }
2023 return false;
2024 }
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035 public boolean isCollapsed(TreePath path) {
2036 return !isExpanded(path);
2037 }
2038
2039
2040
2041
2042
2043
2044
2045
2046 public boolean isCollapsed(int row) {
2047 return !isExpanded(row);
2048 }
2049
2050
2051
2052
2053
2054
2055 public void makeVisible(TreePath path) {
2056 if(path != null) {
2057 TreePath parentPath = path.getParentPath();
2058
2059 if(parentPath != null) {
2060 expandPath(parentPath);
2061 }
2062 }
2063 }
2064
2065
2066
2067
2068
2069
2070
2071
2072 public boolean isVisible(TreePath path) {
2073 if(path != null) {
2074 TreePath parentPath = path.getParentPath();
2075
2076 if(parentPath != null)
2077 return isExpanded(parentPath);
2078
2079 return true;
2080 }
2081 return false;
2082 }
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097 public Rectangle getPathBounds(TreePath path) {
2098 TreeUI tree = getUI();
2099
2100 if(tree != null)
2101 return tree.getPathBounds(this, path);
2102 return null;
2103 }
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113 public Rectangle getRowBounds(int row) {
2114 return getPathBounds(getPathForRow(row));
2115 }
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126 public void scrollPathToVisible(TreePath path) {
2127 if(path != null) {
2128 makeVisible(path);
2129
2130 Rectangle bounds = getPathBounds(path);
2131
2132 if(bounds != null) {
2133 scrollRectToVisible(bounds);
2134 if (accessibleContext != null) {
2135 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange();
2136 }
2137 }
2138 }
2139 }
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150 public void scrollRowToVisible(int row) {
2151 scrollPathToVisible(getPathForRow(row));
2152 }
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164 public TreePath getPathForRow(int row) {
2165 TreeUI tree = getUI();
2166
2167 if(tree != null)
2168 return tree.getPathForRow(this, row);
2169 return null;
2170 }
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181 public int getRowForPath(TreePath path) {
2182 TreeUI tree = getUI();
2183
2184 if(tree != null)
2185 return tree.getRowForPath(this, path);
2186 return -1;
2187 }
2188
2189
2190
2191
2192
2193
2194
2195
2196 public void expandPath(TreePath path) {
2197
2198 TreeModel model = getModel();
2199
2200 if(path != null && model != null &&
2201 !model.isLeaf(path.getLastPathComponent())) {
2202 setExpandedState(path, true);
2203 }
2204 }
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216 public void expandRow(int row) {
2217 expandPath(getPathForRow(row));
2218 }
2219
2220
2221
2222
2223
2224
2225
2226 public void collapsePath(TreePath path) {
2227 setExpandedState(path, false);
2228 }
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239 public void collapseRow(int row) {
2240 collapsePath(getPathForRow(row));
2241 }
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252 public TreePath getPathForLocation(int x, int y) {
2253 TreePath closestPath = getClosestPathForLocation(x, y);
2254
2255 if(closestPath != null) {
2256 Rectangle pathBounds = getPathBounds(closestPath);
2257
2258 if(pathBounds != null &&
2259 x >= pathBounds.x && x < (pathBounds.x + pathBounds.width) &&
2260 y >= pathBounds.y && y < (pathBounds.y + pathBounds.height))
2261 return closestPath;
2262 }
2263 return null;
2264 }
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277 public int getRowForLocation(int x, int y) {
2278 return getRowForPath(getPathForLocation(x, y));
2279 }
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298 public TreePath getClosestPathForLocation(int x, int y) {
2299 TreeUI tree = getUI();
2300
2301 if(tree != null)
2302 return tree.getClosestPathForLocation(this, x, y);
2303 return null;
2304 }
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323 public int getClosestRowForLocation(int x, int y) {
2324 return getRowForPath(getClosestPathForLocation(x, y));
2325 }
2326
2327
2328
2329
2330
2331
2332
2333
2334 public boolean isEditing() {
2335 TreeUI tree = getUI();
2336
2337 if(tree != null)
2338 return tree.isEditing(this);
2339 return false;
2340 }
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357 public boolean stopEditing() {
2358 TreeUI tree = getUI();
2359
2360 if(tree != null)
2361 return tree.stopEditing(this);
2362 return false;
2363 }
2364
2365
2366
2367
2368
2369 public void cancelEditing() {
2370 TreeUI tree = getUI();
2371
2372 if(tree != null)
2373 tree.cancelEditing(this);
2374 }
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384 public void startEditingAtPath(TreePath path) {
2385 TreeUI tree = getUI();
2386
2387 if(tree != null)
2388 tree.startEditingAtPath(this, path);
2389 }
2390
2391
2392
2393
2394
2395
2396 public TreePath getEditingPath() {
2397 TreeUI tree = getUI();
2398
2399 if(tree != null)
2400 return tree.getEditingPath(this);
2401 return null;
2402 }
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427 public void setSelectionModel(TreeSelectionModel selectionModel) {
2428 if(selectionModel == null)
2429 selectionModel = EmptySelectionModel.sharedInstance();
2430
2431 TreeSelectionModel oldValue = this.selectionModel;
2432
2433 if (this.selectionModel != null && selectionRedirector != null) {
2434 this.selectionModel.removeTreeSelectionListener
2435 (selectionRedirector);
2436 }
2437 if (accessibleContext != null) {
2438 this.selectionModel.removeTreeSelectionListener((TreeSelectionListener)accessibleContext);
2439 selectionModel.addTreeSelectionListener((TreeSelectionListener)accessibleContext);
2440 }
2441
2442 this.selectionModel = selectionModel;
2443 if (selectionRedirector != null) {
2444 this.selectionModel.addTreeSelectionListener(selectionRedirector);
2445 }
2446 firePropertyChange(SELECTION_MODEL_PROPERTY, oldValue,
2447 this.selectionModel);
2448
2449 if (accessibleContext != null) {
2450 accessibleContext.firePropertyChange(
2451 AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
2452 Boolean.valueOf(false), Boolean.valueOf(true));
2453 }
2454 }
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465 public TreeSelectionModel getSelectionModel() {
2466 return selectionModel;
2467 }
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495 protected TreePath[] getPathBetweenRows(int index0, int index1) {
2496 TreeUI tree = getUI();
2497 if (tree != null) {
2498 int rowCount = getRowCount();
2499 if (rowCount > 0 && !((index0 < 0 && index1 < 0) ||
2500 (index0 >= rowCount && index1 >= rowCount))){
2501 index0 = Math.min(rowCount - 1, Math.max(index0, 0));
2502 index1 = Math.min(rowCount - 1, Math.max(index1, 0));
2503 int minIndex = Math.min(index0, index1);
2504 int maxIndex = Math.max(index0, index1);
2505 TreePath[] selection = new TreePath[
2506 maxIndex - minIndex + 1];
2507 for(int counter = minIndex; counter <= maxIndex; counter++) {
2508 selection[counter - minIndex] =
2509 tree.getPathForRow(this, counter);
2510 }
2511 return selection;
2512 }
2513 }
2514 return new TreePath[0];
2515 }
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537 public void setSelectionInterval(int index0, int index1) {
2538 TreePath[] paths = getPathBetweenRows(index0, index1);
2539
2540 this.getSelectionModel().setSelectionPaths(paths);
2541 }
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564 public void addSelectionInterval(int index0, int index1) {
2565 TreePath[] paths = getPathBetweenRows(index0, index1);
2566
2567 if (paths != null && paths.length > 0) {
2568 this.getSelectionModel().addSelectionPaths(paths);
2569 }
2570 }
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592 public void removeSelectionInterval(int index0, int index1) {
2593 TreePath[] paths = getPathBetweenRows(index0, index1);
2594
2595 if (paths != null && paths.length > 0) {
2596 this.getSelectionModel().removeSelectionPaths(paths);
2597 }
2598 }
2599
2600
2601
2602
2603
2604
2605
2606 public void removeSelectionPath(TreePath path) {
2607 this.getSelectionModel().removeSelectionPath(path);
2608 }
2609
2610
2611
2612
2613
2614
2615
2616
2617 public void removeSelectionPaths(TreePath[] paths) {
2618 this.getSelectionModel().removeSelectionPaths(paths);
2619 }
2620
2621
2622
2623
2624
2625
2626
2627 public void removeSelectionRow(int row) {
2628 int[] rows = { row };
2629
2630 removeSelectionRows(rows);
2631 }
2632
2633
2634
2635
2636
2637
2638
2639
2640 public void removeSelectionRows(int[] rows) {
2641 TreeUI ui = getUI();
2642
2643 if(ui != null && rows != null) {
2644 int numRows = rows.length;
2645 TreePath[] paths = new TreePath[numRows];
2646
2647 for(int counter = 0; counter < numRows; counter++)
2648 paths[counter] = ui.getPathForRow(this, rows[counter]);
2649 removeSelectionPaths(paths);
2650 }
2651 }
2652
2653
2654
2655
2656 public void clearSelection() {
2657 getSelectionModel().clearSelection();
2658 }
2659
2660
2661
2662
2663
2664
2665 public boolean isSelectionEmpty() {
2666 return getSelectionModel().isSelectionEmpty();
2667 }
2668
2669
2670
2671
2672
2673
2674
2675
2676 public void addTreeExpansionListener(TreeExpansionListener tel) {
2677 if (settingUI) {
2678 uiTreeExpansionListener = tel;
2679 }
2680 listenerList.add(TreeExpansionListener.class, tel);
2681 }
2682
2683
2684
2685
2686
2687
2688 public void removeTreeExpansionListener(TreeExpansionListener tel) {
2689 listenerList.remove(TreeExpansionListener.class, tel);
2690 if (uiTreeExpansionListener == tel) {
2691 uiTreeExpansionListener = null;
2692 }
2693 }
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703 public TreeExpansionListener[] getTreeExpansionListeners() {
2704 return listenerList.getListeners(TreeExpansionListener.class);
2705 }
2706
2707
2708
2709
2710
2711
2712
2713
2714 public void addTreeWillExpandListener(TreeWillExpandListener tel) {
2715 listenerList.add(TreeWillExpandListener.class, tel);
2716 }
2717
2718
2719
2720
2721
2722
2723 public void removeTreeWillExpandListener(TreeWillExpandListener tel) {
2724 listenerList.remove(TreeWillExpandListener.class, tel);
2725 }
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735 public TreeWillExpandListener[] getTreeWillExpandListeners() {
2736 return listenerList.getListeners(TreeWillExpandListener.class);
2737 }
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748 public void fireTreeExpanded(TreePath path) {
2749
2750 Object[] listeners = listenerList.getListenerList();
2751 TreeExpansionEvent e = null;
2752 if (uiTreeExpansionListener != null) {
2753 e = new TreeExpansionEvent(this, path);
2754 uiTreeExpansionListener.treeExpanded(e);
2755 }
2756
2757
2758 for (int i = listeners.length-2; i>=0; i-=2) {
2759 if (listeners[i]==TreeExpansionListener.class &&
2760 listeners[i + 1] != uiTreeExpansionListener) {
2761
2762 if (e == null)
2763 e = new TreeExpansionEvent(this, path);
2764 ((TreeExpansionListener)listeners[i+1]).
2765 treeExpanded(e);
2766 }
2767 }
2768 }
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779 public void fireTreeCollapsed(TreePath path) {
2780
2781 Object[] listeners = listenerList.getListenerList();
2782 TreeExpansionEvent e = null;
2783 if (uiTreeExpansionListener != null) {
2784 e = new TreeExpansionEvent(this, path);
2785 uiTreeExpansionListener.treeCollapsed(e);
2786 }
2787
2788
2789 for (int i = listeners.length-2; i>=0; i-=2) {
2790 if (listeners[i]==TreeExpansionListener.class &&
2791 listeners[i + 1] != uiTreeExpansionListener) {
2792
2793 if (e == null)
2794 e = new TreeExpansionEvent(this, path);
2795 ((TreeExpansionListener)listeners[i+1]).
2796 treeCollapsed(e);
2797 }
2798 }
2799 }
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810 public void fireTreeWillExpand(TreePath path) throws ExpandVetoException {
2811
2812 Object[] listeners = listenerList.getListenerList();
2813 TreeExpansionEvent e = null;
2814
2815
2816 for (int i = listeners.length-2; i>=0; i-=2) {
2817 if (listeners[i]==TreeWillExpandListener.class) {
2818
2819 if (e == null)
2820 e = new TreeExpansionEvent(this, path);
2821 ((TreeWillExpandListener)listeners[i+1]).
2822 treeWillExpand(e);
2823 }
2824 }
2825 }
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836 public void fireTreeWillCollapse(TreePath path) throws ExpandVetoException {
2837
2838 Object[] listeners = listenerList.getListenerList();
2839 TreeExpansionEvent e = null;
2840
2841
2842 for (int i = listeners.length-2; i>=0; i-=2) {
2843 if (listeners[i]==TreeWillExpandListener.class) {
2844
2845 if (e == null)
2846 e = new TreeExpansionEvent(this, path);
2847 ((TreeWillExpandListener)listeners[i+1]).
2848 treeWillCollapse(e);
2849 }
2850 }
2851 }
2852
2853
2854
2855
2856
2857
2858
2859
2860 public void addTreeSelectionListener(TreeSelectionListener tsl) {
2861 listenerList.add(TreeSelectionListener.class,tsl);
2862 if(listenerList.getListenerCount(TreeSelectionListener.class) != 0
2863 && selectionRedirector == null) {
2864 selectionRedirector = new TreeSelectionRedirector();
2865 selectionModel.addTreeSelectionListener(selectionRedirector);
2866 }
2867 }
2868
2869
2870
2871
2872
2873
2874 public void removeTreeSelectionListener(TreeSelectionListener tsl) {
2875 listenerList.remove(TreeSelectionListener.class,tsl);
2876 if(listenerList.getListenerCount(TreeSelectionListener.class) == 0
2877 && selectionRedirector != null) {
2878 selectionModel.removeTreeSelectionListener
2879 (selectionRedirector);
2880 selectionRedirector = null;
2881 }
2882 }
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892 public TreeSelectionListener[] getTreeSelectionListeners() {
2893 return listenerList.getListeners(TreeSelectionListener.class);
2894 }
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906 protected void fireValueChanged(TreeSelectionEvent e) {
2907
2908 Object[] listeners = listenerList.getListenerList();
2909
2910
2911 for (int i = listeners.length-2; i>=0; i-=2) {
2912
2913 if (listeners[i]==TreeSelectionListener.class) {
2914
2915
2916
2917 ((TreeSelectionListener)listeners[i+1]).valueChanged(e);
2918 }
2919 }
2920 }
2921
2922
2923
2924
2925
2926
2927
2928
2929 public void treeDidChange() {
2930 revalidate();
2931 repaint();
2932 }
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947 public void setVisibleRowCount(int newCount) {
2948 int oldCount = visibleRowCount;
2949
2950 visibleRowCount = newCount;
2951 firePropertyChange(VISIBLE_ROW_COUNT_PROPERTY, oldCount,
2952 visibleRowCount);
2953 invalidate();
2954 if (accessibleContext != null) {
2955 ((AccessibleJTree)accessibleContext).fireVisibleDataPropertyChange();
2956 }
2957 }
2958
2959
2960
2961
2962
2963
2964 public int getVisibleRowCount() {
2965 return visibleRowCount;
2966 }
2967
2968
2969
2970
2971 private void expandRoot() {
2972 TreeModel model = getModel();
2973
2974 if(model != null && model.getRoot() != null) {
2975 expandPath(new TreePath(model.getRoot()));
2976 }
2977 }
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995 public TreePath getNextMatch(String prefix, int startingRow,
2996 Position.Bias bias) {
2997
2998 int max = getRowCount();
2999 if (prefix == null) {
3000 throw new IllegalArgumentException();
3001 }
3002 if (startingRow < 0 || startingRow >= max) {
3003 throw new IllegalArgumentException();
3004 }
3005 prefix = prefix.toUpperCase();
3006
3007
3008
3009 int increment = (bias == Position.Bias.Forward) ? 1 : -1;
3010 int row = startingRow;
3011 do {
3012 TreePath path = getPathForRow(row);
3013 String text = convertValueToText(
3014 path.getLastPathComponent(), isRowSelected(row),
3015 isExpanded(row), true, row, false);
3016
3017 if (text.toUpperCase().startsWith(prefix)) {
3018 return path;
3019 }
3020 row = (row + increment + max) % max;
3021 } while (row != startingRow);
3022 return null;
3023 }
3024
3025
3026 private void writeObject(ObjectOutputStream s) throws IOException {
3027 Vector<Object> values = new Vector<Object>();
3028
3029 s.defaultWriteObject();
3030
3031 if(cellRenderer != null && cellRenderer instanceof Serializable) {
3032 values.addElement("cellRenderer");
3033 values.addElement(cellRenderer);
3034 }
3035
3036 if(cellEditor != null && cellEditor instanceof Serializable) {
3037 values.addElement("cellEditor");
3038 values.addElement(cellEditor);
3039 }
3040
3041 if(treeModel != null && treeModel instanceof Serializable) {
3042 values.addElement("treeModel");
3043 values.addElement(treeModel);
3044 }
3045
3046 if(selectionModel != null && selectionModel instanceof Serializable) {
3047 values.addElement("selectionModel");
3048 values.addElement(selectionModel);
3049 }
3050
3051 Object expandedData = getArchivableExpandedState();
3052
3053 if(expandedData != null) {
3054 values.addElement("expandedState");
3055 values.addElement(expandedData);
3056 }
3057
3058 s.writeObject(values);
3059 if (getUIClassID().equals(uiClassID)) {
3060 byte count = JComponent.getWriteObjCounter(this);
3061 JComponent.setWriteObjCounter(this, --count);
3062 if (count == 0 && ui != null) {
3063 ui.installUI(this);
3064 }
3065 }
3066 }
3067
3068 private void readObject(ObjectInputStream s)
3069 throws IOException, ClassNotFoundException {
3070 s.defaultReadObject();
3071
3072
3073
3074 expandedState = new Hashtable<TreePath, Boolean>();
3075
3076 expandedStack = new Stack<Stack<TreePath>>();
3077
3078 Vector values = (Vector)s.readObject();
3079 int indexCounter = 0;
3080 int maxCounter = values.size();
3081
3082 if(indexCounter < maxCounter && values.elementAt(indexCounter).
3083 equals("cellRenderer")) {
3084 cellRenderer = (TreeCellRenderer)values.elementAt(++indexCounter);
3085 indexCounter++;
3086 }
3087 if(indexCounter < maxCounter && values.elementAt(indexCounter).
3088 equals("cellEditor")) {
3089 cellEditor = (TreeCellEditor)values.elementAt(++indexCounter);
3090 indexCounter++;
3091 }
3092 if(indexCounter < maxCounter && values.elementAt(indexCounter).
3093 equals("treeModel")) {
3094 treeModel = (TreeModel)values.elementAt(++indexCounter);
3095 indexCounter++;
3096 }
3097 if(indexCounter < maxCounter && values.elementAt(indexCounter).
3098 equals("selectionModel")) {
3099 selectionModel = (TreeSelectionModel)values.elementAt(++indexCounter);
3100 indexCounter++;
3101 }
3102 if(indexCounter < maxCounter && values.elementAt(indexCounter).
3103 equals("expandedState")) {
3104 unarchiveExpandedState(values.elementAt(++indexCounter));
3105 indexCounter++;
3106 }
3107
3108 if(listenerList.getListenerCount(TreeSelectionListener.class) != 0) {
3109 selectionRedirector = new TreeSelectionRedirector();
3110 selectionModel.addTreeSelectionListener(selectionRedirector);
3111 }
3112
3113 if(treeModel != null) {
3114 treeModelListener = createTreeModelListener();
3115 if(treeModelListener != null)
3116 treeModel.addTreeModelListener(treeModelListener);
3117 }
3118 }
3119
3120
3121
3122
3123
3124
3125 private Object getArchivableExpandedState() {
3126 TreeModel model = getModel();
3127
3128 if(model != null) {
3129 Enumeration<TreePath> paths = expandedState.keys();
3130
3131 if(paths != null) {
3132 Vector<Object> state = new Vector<Object>();
3133
3134 while(paths.hasMoreElements()) {
3135 TreePath path = paths.nextElement();
3136 Object archivePath;
3137
3138 try {
3139 archivePath = getModelIndexsForPath(path);
3140 } catch (Error error) {
3141 archivePath = null;
3142 }
3143 if(archivePath != null) {
3144 state.addElement(archivePath);
3145 state.addElement(expandedState.get(path));
3146 }
3147 }
3148 return state;
3149 }
3150 }
3151 return null;
3152 }
3153
3154
3155
3156
3157
3158 private void unarchiveExpandedState(Object state) {
3159 if(state instanceof Vector) {
3160 Vector paths = (Vector)state;
3161
3162 for(int counter = paths.size() - 1; counter >= 0; counter--) {
3163 Boolean eState = (Boolean)paths.elementAt(counter--);
3164 TreePath path;
3165
3166 try {
3167 path = getPathForIndexs((int[])paths.elementAt(counter));
3168 if(path != null)
3169 expandedState.put(path, eState);
3170 } catch (Error error) {}
3171 }
3172 }
3173 }
3174
3175
3176
3177
3178
3179
3180
3181 private int[] getModelIndexsForPath(TreePath path) {
3182 if(path != null) {
3183 TreeModel model = getModel();
3184 int count = path.getPathCount();
3185 int[] indexs = new int[count - 1];
3186 Object parent = model.getRoot();
3187
3188 for(int counter = 1; counter < count; counter++) {
3189 indexs[counter - 1] = model.getIndexOfChild
3190 (parent, path.getPathComponent(counter));
3191 parent = path.getPathComponent(counter);
3192 if(indexs[counter - 1] < 0)
3193 return null;
3194 }
3195 return indexs;
3196 }
3197 return null;
3198 }
3199
3200
3201
3202
3203
3204
3205
3206 private TreePath getPathForIndexs(int[] indexs) {
3207 if(indexs == null)
3208 return null;
3209
3210 TreeModel model = getModel();
3211
3212 if(model == null)
3213 return null;
3214
3215 int count = indexs.length;
3216 Object parent = model.getRoot();
3217 TreePath parentPath = new TreePath(parent);
3218
3219 for(int counter = 0; counter < count; counter++) {
3220 parent = model.getChild(parent, indexs[counter]);
3221 if(parent == null)
3222 return null;
3223 parentPath = parentPath.pathByAddingChild(parent);
3224 }
3225 return parentPath;
3226 }
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241 protected static class EmptySelectionModel extends
3242 DefaultTreeSelectionModel
3243 {
3244
3245
3246
3247 protected static final EmptySelectionModel sharedInstance =
3248 new EmptySelectionModel();
3249
3250
3251
3252
3253
3254
3255 static public EmptySelectionModel sharedInstance() {
3256 return sharedInstance;
3257 }
3258
3259
3260
3261
3262
3263
3264
3265 public void setSelectionPaths(TreePath[] paths) {}
3266
3267
3268
3269
3270
3271
3272
3273 public void addSelectionPaths(TreePath[] paths) {}
3274
3275
3276
3277
3278
3279
3280
3281 public void removeSelectionPaths(TreePath[] paths) {}
3282
3283
3284
3285
3286
3287
3288
3289
3290 public void setSelectionMode(int mode) {
3291 }
3292
3293
3294
3295
3296
3297
3298
3299
3300 public void setRowMapper(RowMapper mapper) {
3301 }
3302
3303
3304
3305
3306
3307
3308
3309
3310 public void addTreeSelectionListener(TreeSelectionListener listener) {
3311 }
3312
3313
3314
3315
3316
3317
3318
3319
3320 public void removeTreeSelectionListener(
3321 TreeSelectionListener listener) {
3322 }
3323
3324
3325
3326
3327
3328
3329
3330
3331 public void addPropertyChangeListener(
3332 PropertyChangeListener listener) {
3333 }
3334
3335
3336
3337
3338
3339
3340
3341
3342 public void removePropertyChangeListener(
3343 PropertyChangeListener listener) {
3344 }
3345 }
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362 protected class TreeSelectionRedirector implements Serializable,
3363 TreeSelectionListener
3364 {
3365
3366
3367
3368
3369
3370
3371
3372 public void valueChanged(TreeSelectionEvent e) {
3373 TreeSelectionEvent newE;
3374
3375 newE = (TreeSelectionEvent)e.cloneWithSource(JTree.this);
3376 fireValueChanged(newE);
3377 }
3378 }
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391 public Dimension getPreferredScrollableViewportSize() {
3392 int width = getPreferredSize().width;
3393 int visRows = getVisibleRowCount();
3394 int height = -1;
3395
3396 if(isFixedRowHeight())
3397 height = visRows * getRowHeight();
3398 else {
3399 TreeUI ui = getUI();
3400
3401 if (ui != null && visRows > 0) {
3402 int rc = ui.getRowCount(this);
3403
3404 if (rc >= visRows) {
3405 Rectangle bounds = getRowBounds(visRows - 1);
3406 if (bounds != null) {
3407 height = bounds.y + bounds.height;
3408 }
3409 }
3410 else if (rc > 0) {
3411 Rectangle bounds = getRowBounds(0);
3412 if (bounds != null) {
3413 height = bounds.height * visRows;
3414 }
3415 }
3416 }
3417 if (height == -1) {
3418 height = 16 * visRows;
3419 }
3420 }
3421 return new Dimension(width, height);
3422 }
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438 public int getScrollableUnitIncrement(Rectangle visibleRect,
3439 int orientation, int direction) {
3440 if(orientation == SwingConstants.VERTICAL) {
3441 Rectangle rowBounds;
3442 int firstIndex = getClosestRowForLocation
3443 (0, visibleRect.y);
3444
3445 if(firstIndex != -1) {
3446 rowBounds = getRowBounds(firstIndex);
3447 if(rowBounds.y != visibleRect.y) {
3448 if(direction < 0) {
3449
3450 return Math.max(0, (visibleRect.y - rowBounds.y));
3451 }
3452 return (rowBounds.y + rowBounds.height - visibleRect.y);
3453 }
3454 if(direction < 0) {
3455 if(firstIndex != 0) {
3456 rowBounds = getRowBounds(firstIndex - 1);
3457 return rowBounds.height;
3458 }
3459 }
3460 else {
3461 return rowBounds.height;
3462 }
3463 }
3464 return 0;
3465 }
3466 return 4;
3467 }
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482 public int getScrollableBlockIncrement(Rectangle visibleRect,
3483 int orientation, int direction) {
3484 return (orientation == SwingConstants.VERTICAL) ? visibleRect.height :
3485 visibleRect.width;
3486 }
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497 public boolean getScrollableTracksViewportWidth() {
3498 Container parent = SwingUtilities.getUnwrappedParent(this);
3499 if (parent instanceof JViewport) {
3500 return parent.getWidth() > getPreferredSize().width;
3501 }
3502 return false;
3503 }
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514 public boolean getScrollableTracksViewportHeight() {
3515 Container parent = SwingUtilities.getUnwrappedParent(this);
3516 if (parent instanceof JViewport) {
3517 return parent.getHeight() > getPreferredSize().height;
3518 }
3519 return false;
3520 }
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531 protected void setExpandedState(TreePath path, boolean state) {
3532 if(path != null) {
3533
3534 Stack<TreePath> stack;
3535 TreePath parentPath = path.getParentPath();
3536
3537 if (expandedStack.size() == 0) {
3538 stack = new Stack<TreePath>();
3539 }
3540 else {
3541 stack = expandedStack.pop();
3542 }
3543
3544 try {
3545 while(parentPath != null) {
3546 if(isExpanded(parentPath)) {
3547 parentPath = null;
3548 }
3549 else {
3550 stack.push(parentPath);
3551 parentPath = parentPath.getParentPath();
3552 }
3553 }
3554 for(int counter = stack.size() - 1; counter >= 0; counter--) {
3555 parentPath = stack.pop();
3556 if(!isExpanded(parentPath)) {
3557 try {
3558 fireTreeWillExpand(parentPath);
3559 } catch (ExpandVetoException eve) {
3560
3561 return;
3562 }
3563 expandedState.put(parentPath, Boolean.TRUE);
3564 fireTreeExpanded(parentPath);
3565 if (accessibleContext != null) {
3566 ((AccessibleJTree)accessibleContext).
3567 fireVisibleDataPropertyChange();
3568 }
3569 }
3570 }
3571 }
3572 finally {
3573 if (expandedStack.size() < TEMP_STACK_SIZE) {
3574 stack.removeAllElements();
3575 expandedStack.push(stack);
3576 }
3577 }
3578 if(!state) {
3579
3580 Object cValue = expandedState.get(path);
3581
3582 if(cValue != null && ((Boolean)cValue).booleanValue()) {
3583 try {
3584 fireTreeWillCollapse(path);
3585 }
3586 catch (ExpandVetoException eve) {
3587 return;
3588 }
3589 expandedState.put(path, Boolean.FALSE);
3590 fireTreeCollapsed(path);
3591 if (removeDescendantSelectedPaths(path, false) &&
3592 !isPathSelected(path)) {
3593
3594 addSelectionPath(path);
3595 }
3596 if (accessibleContext != null) {
3597 ((AccessibleJTree)accessibleContext).
3598 fireVisibleDataPropertyChange();
3599 }
3600 }
3601 }
3602 else {
3603
3604 Object cValue = expandedState.get(path);
3605
3606 if(cValue == null || !((Boolean)cValue).booleanValue()) {
3607 try {
3608 fireTreeWillExpand(path);
3609 }
3610 catch (ExpandVetoException eve) {
3611 return;
3612 }
3613 expandedState.put(path, Boolean.TRUE);
3614 fireTreeExpanded(path);
3615 if (accessibleContext != null) {
3616 ((AccessibleJTree)accessibleContext).
3617 fireVisibleDataPropertyChange();
3618 }
3619 }
3620 }
3621 }
3622 }
3623
3624
3625
3626
3627
3628
3629 protected Enumeration<TreePath>
3630 getDescendantToggledPaths(TreePath parent)
3631 {
3632 if(parent == null)
3633 return null;
3634
3635 Vector<TreePath> descendants = new Vector<TreePath>();
3636 Enumeration<TreePath> nodes = expandedState.keys();
3637
3638 while(nodes.hasMoreElements()) {
3639 TreePath path = nodes.nextElement();
3640 if(parent.isDescendant(path))
3641 descendants.addElement(path);
3642 }
3643 return descendants.elements();
3644 }
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657 protected void
3658 removeDescendantToggledPaths(Enumeration<TreePath> toRemove)
3659 {
3660 if(toRemove != null) {
3661 while(toRemove.hasMoreElements()) {
3662 Enumeration descendants = getDescendantToggledPaths
3663 (toRemove.nextElement());
3664
3665 if(descendants != null) {
3666 while(descendants.hasMoreElements()) {
3667 expandedState.remove(descendants.nextElement());
3668 }
3669 }
3670 }
3671 }
3672 }
3673
3674
3675
3676
3677
3678 protected void clearToggledPaths() {
3679 expandedState.clear();
3680 }
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691 protected TreeModelListener createTreeModelListener() {
3692 return new TreeModelHandler();
3693 }
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703 protected boolean removeDescendantSelectedPaths(TreePath path,
3704 boolean includePath) {
3705 TreePath[] toRemove = getDescendantSelectedPaths(path, includePath);
3706
3707 if (toRemove != null) {
3708 getSelectionModel().removeSelectionPaths(toRemove);
3709 return true;
3710 }
3711 return false;
3712 }
3713
3714
3715
3716
3717
3718 private TreePath[] getDescendantSelectedPaths(TreePath path,
3719 boolean includePath) {
3720 TreeSelectionModel sm = getSelectionModel();
3721 TreePath[] selPaths = (sm != null) ? sm.getSelectionPaths() :
3722 null;
3723
3724 if(selPaths != null) {
3725 boolean shouldRemove = false;
3726
3727 for(int counter = selPaths.length - 1; counter >= 0; counter--) {
3728 if(selPaths[counter] != null &&
3729 path.isDescendant(selPaths[counter]) &&
3730 (!path.equals(selPaths[counter]) || includePath))
3731 shouldRemove = true;
3732 else
3733 selPaths[counter] = null;
3734 }
3735 if(!shouldRemove) {
3736 selPaths = null;
3737 }
3738 return selPaths;
3739 }
3740 return null;
3741 }
3742
3743
3744
3745
3746
3747 void removeDescendantSelectedPaths(TreeModelEvent e) {
3748 TreePath pPath = e.getTreePath();
3749 Object[] oldChildren = e.getChildren();
3750 TreeSelectionModel sm = getSelectionModel();
3751
3752 if (sm != null && pPath != null && oldChildren != null &&
3753 oldChildren.length > 0) {
3754 for (int counter = oldChildren.length - 1; counter >= 0;
3755 counter--) {
3756
3757
3758 removeDescendantSelectedPaths(pPath.pathByAddingChild
3759 (oldChildren[counter]), true);
3760 }
3761 }
3762 }
3763
3764
3765
3766
3767
3768
3769 protected class TreeModelHandler implements TreeModelListener {
3770 public void treeNodesChanged(TreeModelEvent e) { }
3771
3772 public void treeNodesInserted(TreeModelEvent e) { }
3773
3774 public void treeStructureChanged(TreeModelEvent e) {
3775 if(e == null)
3776 return;
3777
3778
3779
3780
3781
3782 TreePath parent = e.getTreePath();
3783
3784 if(parent == null)
3785 return;
3786
3787 if (parent.getPathCount() == 1) {
3788
3789 clearToggledPaths();
3790 if(treeModel.getRoot() != null &&
3791 !treeModel.isLeaf(treeModel.getRoot())) {
3792
3793 expandedState.put(parent, Boolean.TRUE);
3794 }
3795 }
3796 else if(expandedState.get(parent) != null) {
3797 Vector<TreePath> toRemove = new Vector<TreePath>(1);
3798 boolean isExpanded = isExpanded(parent);
3799
3800 toRemove.addElement(parent);
3801 removeDescendantToggledPaths(toRemove.elements());
3802 if(isExpanded) {
3803 TreeModel model = getModel();
3804
3805 if(model == null || model.isLeaf
3806 (parent.getLastPathComponent()))
3807 collapsePath(parent);
3808 else
3809 expandedState.put(parent, Boolean.TRUE);
3810 }
3811 }
3812 removeDescendantSelectedPaths(parent, false);
3813 }
3814
3815 public void treeNodesRemoved(TreeModelEvent e) {
3816 if(e == null)
3817 return;
3818
3819 TreePath parent = e.getTreePath();
3820 Object[] children = e.getChildren();
3821
3822 if(children == null)
3823 return;
3824
3825 TreePath rPath;
3826 Vector<TreePath> toRemove
3827 = new Vector<TreePath>(Math.max(1, children.length));
3828
3829 for(int counter = children.length - 1; counter >= 0; counter--) {
3830 rPath = parent.pathByAddingChild(children[counter]);
3831 if(expandedState.get(rPath) != null)
3832 toRemove.addElement(rPath);
3833 }
3834 if(toRemove.size() > 0)
3835 removeDescendantToggledPaths(toRemove.elements());
3836
3837 TreeModel model = getModel();
3838
3839 if(model == null || model.isLeaf(parent.getLastPathComponent()))
3840 expandedState.remove(parent);
3841
3842 removeDescendantSelectedPaths(e);
3843 }
3844 }
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862 public static class DynamicUtilTreeNode extends DefaultMutableTreeNode {
3863
3864
3865
3866
3867 protected boolean hasChildren;
3868
3869 protected Object childValue;
3870
3871 protected boolean loadedChildren;
3872
3873
3874
3875
3876
3877
3878
3879
3880 public static void createChildren(DefaultMutableTreeNode parent,
3881 Object children) {
3882 if(children instanceof Vector) {
3883 Vector childVector = (Vector)children;
3884
3885 for(int counter = 0, maxCounter = childVector.size();
3886 counter < maxCounter; counter++)
3887 parent.add(new DynamicUtilTreeNode
3888 (childVector.elementAt(counter),
3889 childVector.elementAt(counter)));
3890 }
3891 else if(children instanceof Hashtable) {
3892 Hashtable childHT = (Hashtable)children;
3893 Enumeration keys = childHT.keys();
3894 Object aKey;
3895
3896 while(keys.hasMoreElements()) {
3897 aKey = keys.nextElement();
3898 parent.add(new DynamicUtilTreeNode(aKey,
3899 childHT.get(aKey)));
3900 }
3901 }
3902 else if(children instanceof Object[]) {
3903 Object[] childArray = (Object[])children;
3904
3905 for(int counter = 0, maxCounter = childArray.length;
3906 counter < maxCounter; counter++)
3907 parent.add(new DynamicUtilTreeNode(childArray[counter],
3908 childArray[counter]));
3909 }
3910 }
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929 public DynamicUtilTreeNode(Object value, Object children) {
3930 super(value);
3931 loadedChildren = false;
3932 childValue = children;
3933 if(children != null) {
3934 if(children instanceof Vector)
3935 setAllowsChildren(true);
3936 else if(children instanceof Hashtable)
3937 setAllowsChildren(true);
3938 else if(children instanceof Object[])
3939 setAllowsChildren(true);
3940 else
3941 setAllowsChildren(false);
3942 }
3943 else
3944 setAllowsChildren(false);
3945 }
3946
3947
3948
3949
3950
3951
3952
3953
3954 public boolean isLeaf() {
3955 return !getAllowsChildren();
3956 }
3957
3958
3959
3960
3961
3962
3963 public int getChildCount() {
3964 if(!loadedChildren)
3965 loadChildren();
3966 return super.getChildCount();
3967 }
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977 protected void loadChildren() {
3978 loadedChildren = true;
3979 createChildren(this, childValue);
3980 }
3981
3982
3983
3984
3985 public TreeNode getChildAt(int index) {
3986 if(!loadedChildren)
3987 loadChildren();
3988 return super.getChildAt(index);
3989 }
3990
3991
3992
3993
3994 public Enumeration children() {
3995 if(!loadedChildren)
3996 loadChildren();
3997 return super.children();
3998 }
3999 }
4000
4001 void setUIProperty(String propertyName, Object value) {
4002 if (propertyName == "rowHeight") {
4003 if (!rowHeightSet) {
4004 setRowHeight(((Number)value).intValue());
4005 rowHeightSet = false;
4006 }
4007 } else if (propertyName == "scrollsOnExpand") {
4008 if (!scrollsOnExpandSet) {
4009 setScrollsOnExpand(((Boolean)value).booleanValue());
4010 scrollsOnExpandSet = false;
4011 }
4012 } else if (propertyName == "showsRootHandles") {
4013 if (!showsRootHandlesSet) {
4014 setShowsRootHandles(((Boolean)value).booleanValue());
4015 showsRootHandlesSet = false;
4016 }
4017 } else {
4018 super.setUIProperty(propertyName, value);
4019 }
4020 }
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033 protected String paramString() {
4034 String rootVisibleString = (rootVisible ?
4035 "true" : "false");
4036 String showsRootHandlesString = (showsRootHandles ?
4037 "true" : "false");
4038 String editableString = (editable ?
4039 "true" : "false");
4040 String largeModelString = (largeModel ?
4041 "true" : "false");
4042 String invokesStopCellEditingString = (invokesStopCellEditing ?
4043 "true" : "false");
4044 String scrollsOnExpandString = (scrollsOnExpand ?
4045 "true" : "false");
4046
4047 return super.paramString() +
4048 ",editable=" + editableString +
4049 ",invokesStopCellEditing=" + invokesStopCellEditingString +
4050 ",largeModel=" + largeModelString +
4051 ",rootVisible=" + rootVisibleString +
4052 ",rowHeight=" + rowHeight +
4053 ",scrollsOnExpand=" + scrollsOnExpandString +
4054 ",showsRootHandles=" + showsRootHandlesString +
4055 ",toggleClickCount=" + toggleClickCount +
4056 ",visibleRowCount=" + visibleRowCount;
4057 }
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072 public AccessibleContext getAccessibleContext() {
4073 if (accessibleContext == null) {
4074 accessibleContext = new AccessibleJTree();
4075 }
4076 return accessibleContext;
4077 }
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093 protected class AccessibleJTree extends AccessibleJComponent
4094 implements AccessibleSelection, TreeSelectionListener,
4095 TreeModelListener, TreeExpansionListener {
4096
4097 TreePath leadSelectionPath;
4098 Accessible leadSelectionAccessible;
4099
4100 public AccessibleJTree() {
4101
4102 TreeModel model = JTree.this.getModel();
4103 if (model != null) {
4104 model.addTreeModelListener(this);
4105 }
4106 JTree.this.addTreeExpansionListener(this);
4107 JTree.this.addTreeSelectionListener(this);
4108 leadSelectionPath = JTree.this.getLeadSelectionPath();
4109 leadSelectionAccessible = (leadSelectionPath != null)
4110 ? new AccessibleJTreeNode(JTree.this,
4111 leadSelectionPath,
4112 JTree.this)
4113 : null;
4114 }
4115
4116
4117
4118
4119
4120
4121
4122
4123 public void valueChanged(TreeSelectionEvent e) {
4124
4125
4126 TreePath oldLeadSelectionPath = e.getOldLeadSelectionPath();
4127 leadSelectionPath = e.getNewLeadSelectionPath();
4128
4129 if (oldLeadSelectionPath != leadSelectionPath) {
4130
4131
4132 Accessible oldLSA = leadSelectionAccessible;
4133 leadSelectionAccessible = (leadSelectionPath != null)
4134 ? new AccessibleJTreeNode(JTree.this,
4135 leadSelectionPath,
4136 null)
4137 : null;
4138 firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY,
4139 oldLSA, leadSelectionAccessible);
4140 }
4141 firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
4142 Boolean.valueOf(false), Boolean.valueOf(true));
4143 }
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154 public void fireVisibleDataPropertyChange() {
4155 firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
4156 Boolean.valueOf(false), Boolean.valueOf(true));
4157 }
4158
4159
4160
4161
4162
4163
4164
4165
4166 public void treeNodesChanged(TreeModelEvent e) {
4167 fireVisibleDataPropertyChange();
4168 }
4169
4170
4171
4172
4173
4174
4175 public void treeNodesInserted(TreeModelEvent e) {
4176 fireVisibleDataPropertyChange();
4177 }
4178
4179
4180
4181
4182
4183
4184 public void treeNodesRemoved(TreeModelEvent e) {
4185 fireVisibleDataPropertyChange();
4186 }
4187
4188
4189
4190
4191
4192
4193 public void treeStructureChanged(TreeModelEvent e) {
4194 fireVisibleDataPropertyChange();
4195 }
4196
4197
4198
4199
4200
4201
4202 public void treeCollapsed(TreeExpansionEvent e) {
4203 fireVisibleDataPropertyChange();
4204 TreePath path = e.getPath();
4205 if (path != null) {
4206
4207
4208 AccessibleJTreeNode node = new AccessibleJTreeNode(JTree.this,
4209 path,
4210 null);
4211 PropertyChangeEvent pce = new PropertyChangeEvent(node,
4212 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
4213 AccessibleState.EXPANDED,
4214 AccessibleState.COLLAPSED);
4215 firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
4216 null, pce);
4217 }
4218 }
4219
4220
4221
4222
4223
4224
4225 public void treeExpanded(TreeExpansionEvent e) {
4226 fireVisibleDataPropertyChange();
4227 TreePath path = e.getPath();
4228 if (path != null) {
4229
4230
4231
4232 AccessibleJTreeNode node = new AccessibleJTreeNode(JTree.this,
4233 path,
4234 null);
4235 PropertyChangeEvent pce = new PropertyChangeEvent(node,
4236 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
4237 AccessibleState.COLLAPSED,
4238 AccessibleState.EXPANDED);
4239 firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
4240 null, pce);
4241 }
4242 }
4243
4244
4245 private AccessibleContext getCurrentAccessibleContext() {
4246 Component c = getCurrentComponent();
4247 if (c instanceof Accessible) {
4248 return c.getAccessibleContext();
4249 } else {
4250 return null;
4251 }
4252 }
4253
4254 private Component getCurrentComponent() {
4255
4256
4257
4258 TreeModel model = JTree.this.getModel();
4259 if (model == null) {
4260 return null;
4261 }
4262 TreePath path = new TreePath(model.getRoot());
4263 if (JTree.this.isVisible(path)) {
4264 TreeCellRenderer r = JTree.this.getCellRenderer();
4265 TreeUI ui = JTree.this.getUI();
4266 if (ui != null) {
4267 int row = ui.getRowForPath(JTree.this, path);
4268 int lsr = JTree.this.getLeadSelectionRow();
4269 boolean hasFocus = JTree.this.isFocusOwner()
4270 && (lsr == row);
4271 boolean selected = JTree.this.isPathSelected(path);
4272 boolean expanded = JTree.this.isExpanded(path);
4273
4274 return r.getTreeCellRendererComponent(JTree.this,
4275 model.getRoot(), selected, expanded,
4276 model.isLeaf(model.getRoot()), row, hasFocus);
4277 }
4278 }
4279 return null;
4280 }
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291 public AccessibleRole getAccessibleRole() {
4292 return AccessibleRole.TREE;
4293 }
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304 public Accessible getAccessibleAt(Point p) {
4305 TreePath path = getClosestPathForLocation(p.x, p.y);
4306 if (path != null) {
4307
4308 return new AccessibleJTreeNode(JTree.this, path, null);
4309 } else {
4310 return null;
4311 }
4312 }
4313
4314
4315
4316
4317
4318
4319
4320 public int getAccessibleChildrenCount() {
4321 TreeModel model = JTree.this.getModel();
4322 if (model == null) {
4323 return 0;
4324 }
4325 if (isRootVisible()) {
4326 return 1;
4327 }
4328
4329
4330 return model.getChildCount(model.getRoot());
4331 }
4332
4333
4334
4335
4336
4337
4338
4339 public Accessible getAccessibleChild(int i) {
4340 TreeModel model = JTree.this.getModel();
4341 if (model == null) {
4342 return null;
4343 }
4344 if (isRootVisible()) {
4345 if (i == 0) {
4346 Object[] objPath = { model.getRoot() };
4347 TreePath path = new TreePath(objPath);
4348 return new AccessibleJTreeNode(JTree.this, path, JTree.this);
4349 } else {
4350 return null;
4351 }
4352 }
4353
4354
4355 int count = model.getChildCount(model.getRoot());
4356 if (i < 0 || i >= count) {
4357 return null;
4358 }
4359 Object obj = model.getChild(model.getRoot(), i);
4360 Object[] objPath = { model.getRoot(), obj };
4361 TreePath path = new TreePath(objPath);
4362 return new AccessibleJTreeNode(JTree.this, path, JTree.this);
4363 }
4364
4365
4366
4367
4368
4369
4370
4371
4372 public int getAccessibleIndexInParent() {
4373
4374 return super.getAccessibleIndexInParent();
4375 }
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386 public AccessibleSelection getAccessibleSelection() {
4387 return this;
4388 }
4389
4390
4391
4392
4393
4394
4395
4396 public int getAccessibleSelectionCount() {
4397 Object[] rootPath = new Object[1];
4398 rootPath[0] = treeModel.getRoot();
4399 TreePath childPath = new TreePath(rootPath);
4400 if (JTree.this.isPathSelected(childPath)) {
4401 return 1;
4402 } else {
4403 return 0;
4404 }
4405 }
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416 public Accessible getAccessibleSelection(int i) {
4417
4418 if (i == 0) {
4419 Object[] rootPath = new Object[1];
4420 rootPath[0] = treeModel.getRoot();
4421 TreePath childPath = new TreePath(rootPath);
4422 if (JTree.this.isPathSelected(childPath)) {
4423 return new AccessibleJTreeNode(JTree.this, childPath, JTree.this);
4424 }
4425 }
4426 return null;
4427 }
4428
4429
4430
4431
4432
4433
4434
4435 public boolean isAccessibleChildSelected(int i) {
4436
4437 if (i == 0) {
4438 Object[] rootPath = new Object[1];
4439 rootPath[0] = treeModel.getRoot();
4440 TreePath childPath = new TreePath(rootPath);
4441 return JTree.this.isPathSelected(childPath);
4442 } else {
4443 return false;
4444 }
4445 }
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456 public void addAccessibleSelection(int i) {
4457 TreeModel model = JTree.this.getModel();
4458 if (model != null) {
4459 if (i == 0) {
4460 Object[] objPath = {model.getRoot()};
4461 TreePath path = new TreePath(objPath);
4462 JTree.this.addSelectionPath(path);
4463 }
4464 }
4465 }
4466
4467
4468
4469
4470
4471
4472
4473
4474 public void removeAccessibleSelection(int i) {
4475 TreeModel model = JTree.this.getModel();
4476 if (model != null) {
4477 if (i == 0) {
4478 Object[] objPath = {model.getRoot()};
4479 TreePath path = new TreePath(objPath);
4480 JTree.this.removeSelectionPath(path);
4481 }
4482 }
4483 }
4484
4485
4486
4487
4488
4489 public void clearAccessibleSelection() {
4490 int childCount = getAccessibleChildrenCount();
4491 for (int i = 0; i < childCount; i++) {
4492 removeAccessibleSelection(i);
4493 }
4494 }
4495
4496
4497
4498
4499
4500 public void selectAllAccessibleSelection() {
4501 TreeModel model = JTree.this.getModel();
4502 if (model != null) {
4503 Object[] objPath = {model.getRoot()};
4504 TreePath path = new TreePath(objPath);
4505 JTree.this.addSelectionPath(path);
4506 }
4507 }
4508
4509
4510
4511
4512
4513
4514 protected class AccessibleJTreeNode extends AccessibleContext
4515 implements Accessible, AccessibleComponent, AccessibleSelection,
4516 AccessibleAction {
4517
4518 private JTree tree = null;
4519 private TreeModel treeModel = null;
4520 private Object obj = null;
4521 private TreePath path = null;
4522 private Accessible accessibleParent = null;
4523 private int index = 0;
4524 private boolean isLeaf = false;
4525
4526
4527
4528
4529
4530 public AccessibleJTreeNode(JTree t, TreePath p, Accessible ap) {
4531 tree = t;
4532 path = p;
4533 accessibleParent = ap;
4534 treeModel = t.getModel();
4535 obj = p.getLastPathComponent();
4536 if (treeModel != null) {
4537 isLeaf = treeModel.isLeaf(obj);
4538 }
4539 }
4540
4541 private TreePath getChildTreePath(int i) {
4542
4543
4544 if (i < 0 || i >= getAccessibleChildrenCount()) {
4545 return null;
4546 } else {
4547 Object childObj = treeModel.getChild(obj, i);
4548 Object[] objPath = path.getPath();
4549 Object[] objChildPath = new Object[objPath.length+1];
4550 java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length);
4551 objChildPath[objChildPath.length-1] = childObj;
4552 return new TreePath(objChildPath);
4553 }
4554 }
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564 public AccessibleContext getAccessibleContext() {
4565 return this;
4566 }
4567
4568 private AccessibleContext getCurrentAccessibleContext() {
4569 Component c = getCurrentComponent();
4570 if (c instanceof Accessible) {
4571 return c.getAccessibleContext();
4572 } else {
4573 return null;
4574 }
4575 }
4576
4577 private Component getCurrentComponent() {
4578
4579
4580
4581 if (tree.isVisible(path)) {
4582 TreeCellRenderer r = tree.getCellRenderer();
4583 if (r == null) {
4584 return null;
4585 }
4586 TreeUI ui = tree.getUI();
4587 if (ui != null) {
4588 int row = ui.getRowForPath(JTree.this, path);
4589 boolean selected = tree.isPathSelected(path);
4590 boolean expanded = tree.isExpanded(path);
4591 boolean hasFocus = false;
4592 return r.getTreeCellRendererComponent(tree, obj,
4593 selected, expanded, isLeaf, row, hasFocus);
4594 }
4595 }
4596 return null;
4597 }
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607 public String getAccessibleName() {
4608 AccessibleContext ac = getCurrentAccessibleContext();
4609 if (ac != null) {
4610 String name = ac.getAccessibleName();
4611 if ((name != null) && (name != "")) {
4612 return ac.getAccessibleName();
4613 } else {
4614 return null;
4615 }
4616 }
4617 if ((accessibleName != null) && (accessibleName != "")) {
4618 return accessibleName;
4619 } else {
4620
4621 return (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
4622 }
4623 }
4624
4625
4626
4627
4628
4629
4630 public void setAccessibleName(String s) {
4631 AccessibleContext ac = getCurrentAccessibleContext();
4632 if (ac != null) {
4633 ac.setAccessibleName(s);
4634 } else {
4635 super.setAccessibleName(s);
4636 }
4637 }
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648 public String getAccessibleDescription() {
4649 AccessibleContext ac = getCurrentAccessibleContext();
4650 if (ac != null) {
4651 return ac.getAccessibleDescription();
4652 } else {
4653 return super.getAccessibleDescription();
4654 }
4655 }
4656
4657
4658
4659
4660
4661
4662 public void setAccessibleDescription(String s) {
4663 AccessibleContext ac = getCurrentAccessibleContext();
4664 if (ac != null) {
4665 ac.setAccessibleDescription(s);
4666 } else {
4667 super.setAccessibleDescription(s);
4668 }
4669 }
4670
4671
4672
4673
4674
4675
4676
4677 public AccessibleRole getAccessibleRole() {
4678 AccessibleContext ac = getCurrentAccessibleContext();
4679 if (ac != null) {
4680 return ac.getAccessibleRole();
4681 } else {
4682 return AccessibleRole.UNKNOWN;
4683 }
4684 }
4685
4686
4687
4688
4689
4690
4691
4692
4693 public AccessibleStateSet getAccessibleStateSet() {
4694 AccessibleContext ac = getCurrentAccessibleContext();
4695 AccessibleStateSet states;
4696 if (ac != null) {
4697 states = ac.getAccessibleStateSet();
4698 } else {
4699 states = new AccessibleStateSet();
4700 }
4701
4702
4703 if (isShowing()) {
4704 states.add(AccessibleState.SHOWING);
4705 } else if (states.contains(AccessibleState.SHOWING)) {
4706 states.remove(AccessibleState.SHOWING);
4707 }
4708 if (isVisible()) {
4709 states.add(AccessibleState.VISIBLE);
4710 } else if (states.contains(AccessibleState.VISIBLE)) {
4711 states.remove(AccessibleState.VISIBLE);
4712 }
4713 if (tree.isPathSelected(path)){
4714 states.add(AccessibleState.SELECTED);
4715 }
4716 if (path == getLeadSelectionPath()) {
4717 states.add(AccessibleState.ACTIVE);
4718 }
4719 if (!isLeaf) {
4720 states.add(AccessibleState.EXPANDABLE);
4721 }
4722 if (tree.isExpanded(path)) {
4723 states.add(AccessibleState.EXPANDED);
4724 } else {
4725 states.add(AccessibleState.COLLAPSED);
4726 }
4727 if (tree.isEditable()) {
4728 states.add(AccessibleState.EDITABLE);
4729 }
4730 return states;
4731 }
4732
4733
4734
4735
4736
4737
4738
4739 public Accessible getAccessibleParent() {
4740
4741
4742 if (accessibleParent == null) {
4743 Object[] objPath = path.getPath();
4744 if (objPath.length > 1) {
4745 Object objParent = objPath[objPath.length-2];
4746 if (treeModel != null) {
4747 index = treeModel.getIndexOfChild(objParent, obj);
4748 }
4749 Object[] objParentPath = new Object[objPath.length-1];
4750 java.lang.System.arraycopy(objPath, 0, objParentPath,
4751 0, objPath.length-1);
4752 TreePath parentPath = new TreePath(objParentPath);
4753 accessibleParent = new AccessibleJTreeNode(tree,
4754 parentPath,
4755 null);
4756 this.setAccessibleParent(accessibleParent);
4757 } else if (treeModel != null) {
4758 accessibleParent = tree;
4759 index = 0;
4760 this.setAccessibleParent(accessibleParent);
4761 }
4762 }
4763 return accessibleParent;
4764 }
4765
4766
4767
4768
4769
4770
4771
4772
4773 public int getAccessibleIndexInParent() {
4774
4775 if (accessibleParent == null) {
4776 getAccessibleParent();
4777 }
4778 Object[] objPath = path.getPath();
4779 if (objPath.length > 1) {
4780 Object objParent = objPath[objPath.length-2];
4781 if (treeModel != null) {
4782 index = treeModel.getIndexOfChild(objParent, obj);
4783 }
4784 }
4785 return index;
4786 }
4787
4788
4789
4790
4791
4792
4793 public int getAccessibleChildrenCount() {
4794
4795
4796 return treeModel.getChildCount(obj);
4797 }
4798
4799
4800
4801
4802
4803
4804
4805 public Accessible getAccessibleChild(int i) {
4806
4807
4808 if (i < 0 || i >= getAccessibleChildrenCount()) {
4809 return null;
4810 } else {
4811 Object childObj = treeModel.getChild(obj, i);
4812 Object[] objPath = path.getPath();
4813 Object[] objChildPath = new Object[objPath.length+1];
4814 java.lang.System.arraycopy(objPath, 0, objChildPath, 0, objPath.length);
4815 objChildPath[objChildPath.length-1] = childObj;
4816 TreePath childPath = new TreePath(objChildPath);
4817 return new AccessibleJTreeNode(JTree.this, childPath, this);
4818 }
4819 }
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833 public Locale getLocale() {
4834 AccessibleContext ac = getCurrentAccessibleContext();
4835 if (ac != null) {
4836 return ac.getLocale();
4837 } else {
4838 return tree.getLocale();
4839 }
4840 }
4841
4842
4843
4844
4845
4846
4847
4848 public void addPropertyChangeListener(PropertyChangeListener l) {
4849 AccessibleContext ac = getCurrentAccessibleContext();
4850 if (ac != null) {
4851 ac.addPropertyChangeListener(l);
4852 } else {
4853 super.addPropertyChangeListener(l);
4854 }
4855 }
4856
4857
4858
4859
4860
4861
4862
4863
4864 public void removePropertyChangeListener(PropertyChangeListener l) {
4865 AccessibleContext ac = getCurrentAccessibleContext();
4866 if (ac != null) {
4867 ac.removePropertyChangeListener(l);
4868 } else {
4869 super.removePropertyChangeListener(l);
4870 }
4871 }
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881 public AccessibleAction getAccessibleAction() {
4882 return this;
4883 }
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893 public AccessibleComponent getAccessibleComponent() {
4894 return this;
4895 }
4896
4897
4898
4899
4900
4901
4902
4903 public AccessibleSelection getAccessibleSelection() {
4904 AccessibleContext ac = getCurrentAccessibleContext();
4905 if (ac != null && isLeaf) {
4906 return getCurrentAccessibleContext().getAccessibleSelection();
4907 } else {
4908 return this;
4909 }
4910 }
4911
4912
4913
4914
4915
4916
4917
4918 public AccessibleText getAccessibleText() {
4919 AccessibleContext ac = getCurrentAccessibleContext();
4920 if (ac != null) {
4921 return getCurrentAccessibleContext().getAccessibleText();
4922 } else {
4923 return null;
4924 }
4925 }
4926
4927
4928
4929
4930
4931
4932
4933 public AccessibleValue getAccessibleValue() {
4934 AccessibleContext ac = getCurrentAccessibleContext();
4935 if (ac != null) {
4936 return getCurrentAccessibleContext().getAccessibleValue();
4937 } else {
4938 return null;
4939 }
4940 }
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951 public Color getBackground() {
4952 AccessibleContext ac = getCurrentAccessibleContext();
4953 if (ac instanceof AccessibleComponent) {
4954 return ((AccessibleComponent) ac).getBackground();
4955 } else {
4956 Component c = getCurrentComponent();
4957 if (c != null) {
4958 return c.getBackground();
4959 } else {
4960 return null;
4961 }
4962 }
4963 }
4964
4965
4966
4967
4968
4969
4970 public void setBackground(Color c) {
4971 AccessibleContext ac = getCurrentAccessibleContext();
4972 if (ac instanceof AccessibleComponent) {
4973 ((AccessibleComponent) ac).setBackground(c);
4974 } else {
4975 Component cp = getCurrentComponent();
4976 if (cp != null) {
4977 cp.setBackground(c);
4978 }
4979 }
4980 }
4981
4982
4983
4984
4985
4986
4987
4988
4989 public Color getForeground() {
4990 AccessibleContext ac = getCurrentAccessibleContext();
4991 if (ac instanceof AccessibleComponent) {
4992 return ((AccessibleComponent) ac).getForeground();
4993 } else {
4994 Component c = getCurrentComponent();
4995 if (c != null) {
4996 return c.getForeground();
4997 } else {
4998 return null;
4999 }
5000 }
5001 }
5002
5003 public void setForeground(Color c) {
5004 AccessibleContext ac = getCurrentAccessibleContext();
5005 if (ac instanceof AccessibleComponent) {
5006 ((AccessibleComponent) ac).setForeground(c);
5007 } else {
5008 Component cp = getCurrentComponent();
5009 if (cp != null) {
5010 cp.setForeground(c);
5011 }
5012 }
5013 }
5014
5015 public Cursor getCursor() {
5016 AccessibleContext ac = getCurrentAccessibleContext();
5017 if (ac instanceof AccessibleComponent) {
5018 return ((AccessibleComponent) ac).getCursor();
5019 } else {
5020 Component c = getCurrentComponent();
5021 if (c != null) {
5022 return c.getCursor();
5023 } else {
5024 Accessible ap = getAccessibleParent();
5025 if (ap instanceof AccessibleComponent) {
5026 return ((AccessibleComponent) ap).getCursor();
5027 } else {
5028 return null;
5029 }
5030 }
5031 }
5032 }
5033
5034 public void setCursor(Cursor c) {
5035 AccessibleContext ac = getCurrentAccessibleContext();
5036 if (ac instanceof AccessibleComponent) {
5037 ((AccessibleComponent) ac).setCursor(c);
5038 } else {
5039 Component cp = getCurrentComponent();
5040 if (cp != null) {
5041 cp.setCursor(c);
5042 }
5043 }
5044 }
5045
5046 public Font getFont() {
5047 AccessibleContext ac = getCurrentAccessibleContext();
5048 if (ac instanceof AccessibleComponent) {
5049 return ((AccessibleComponent) ac).getFont();
5050 } else {
5051 Component c = getCurrentComponent();
5052 if (c != null) {
5053 return c.getFont();
5054 } else {
5055 return null;
5056 }
5057 }
5058 }
5059
5060 public void setFont(Font f) {
5061 AccessibleContext ac = getCurrentAccessibleContext();
5062 if (ac instanceof AccessibleComponent) {
5063 ((AccessibleComponent) ac).setFont(f);
5064 } else {
5065 Component c = getCurrentComponent();
5066 if (c != null) {
5067 c.setFont(f);
5068 }
5069 }
5070 }
5071
5072 public FontMetrics getFontMetrics(Font f) {
5073 AccessibleContext ac = getCurrentAccessibleContext();
5074 if (ac instanceof AccessibleComponent) {
5075 return ((AccessibleComponent) ac).getFontMetrics(f);
5076 } else {
5077 Component c = getCurrentComponent();
5078 if (c != null) {
5079 return c.getFontMetrics(f);
5080 } else {
5081 return null;
5082 }
5083 }
5084 }
5085
5086 public boolean isEnabled() {
5087 AccessibleContext ac = getCurrentAccessibleContext();
5088 if (ac instanceof AccessibleComponent) {
5089 return ((AccessibleComponent) ac).isEnabled();
5090 } else {
5091 Component c = getCurrentComponent();
5092 if (c != null) {
5093 return c.isEnabled();
5094 } else {
5095 return false;
5096 }
5097 }
5098 }
5099
5100 public void setEnabled(boolean b) {
5101 AccessibleContext ac = getCurrentAccessibleContext();
5102 if (ac instanceof AccessibleComponent) {
5103 ((AccessibleComponent) ac).setEnabled(b);
5104 } else {
5105 Component c = getCurrentComponent();
5106 if (c != null) {
5107 c.setEnabled(b);
5108 }
5109 }
5110 }
5111
5112 public boolean isVisible() {
5113 Rectangle pathBounds = tree.getPathBounds(path);
5114 Rectangle parentBounds = tree.getVisibleRect();
5115 return pathBounds != null && parentBounds != null &&
5116 parentBounds.intersects(pathBounds);
5117 }
5118
5119 public void setVisible(boolean b) {
5120 }
5121
5122 public boolean isShowing() {
5123 return (tree.isShowing() && isVisible());
5124 }
5125
5126 public boolean contains(Point p) {
5127 AccessibleContext ac = getCurrentAccessibleContext();
5128 if (ac instanceof AccessibleComponent) {
5129 Rectangle r = ((AccessibleComponent) ac).getBounds();
5130 return r.contains(p);
5131 } else {
5132 Component c = getCurrentComponent();
5133 if (c != null) {
5134 Rectangle r = c.getBounds();
5135 return r.contains(p);
5136 } else {
5137 return getBounds().contains(p);
5138 }
5139 }
5140 }
5141
5142 public Point getLocationOnScreen() {
5143 if (tree != null) {
5144 Point treeLocation = tree.getLocationOnScreen();
5145 Rectangle pathBounds = tree.getPathBounds(path);
5146 if (treeLocation != null && pathBounds != null) {
5147 Point nodeLocation = new Point(pathBounds.x,
5148 pathBounds.y);
5149 nodeLocation.translate(treeLocation.x, treeLocation.y);
5150 return nodeLocation;
5151 } else {
5152 return null;
5153 }
5154 } else {
5155 return null;
5156 }
5157 }
5158
5159 protected Point getLocationInJTree() {
5160 Rectangle r = tree.getPathBounds(path);
5161 if (r != null) {
5162 return r.getLocation();
5163 } else {
5164 return null;
5165 }
5166 }
5167
5168 public Point getLocation() {
5169 Rectangle r = getBounds();
5170 if (r != null) {
5171 return r.getLocation();
5172 } else {
5173 return null;
5174 }
5175 }
5176
5177 public void setLocation(Point p) {
5178 }
5179
5180 public Rectangle getBounds() {
5181 Rectangle r = tree.getPathBounds(path);
5182 Accessible parent = getAccessibleParent();
5183 if (parent != null) {
5184 if (parent instanceof AccessibleJTreeNode) {
5185 Point parentLoc = ((AccessibleJTreeNode) parent).getLocationInJTree();
5186 if (parentLoc != null && r != null) {
5187 r.translate(-parentLoc.x, -parentLoc.y);
5188 } else {
5189 return null;
5190 }
5191 }
5192 }
5193 return r;
5194 }
5195
5196 public void setBounds(Rectangle r) {
5197 AccessibleContext ac = getCurrentAccessibleContext();
5198 if (ac instanceof AccessibleComponent) {
5199 ((AccessibleComponent) ac).setBounds(r);
5200 } else {
5201 Component c = getCurrentComponent();
5202 if (c != null) {
5203 c.setBounds(r);
5204 }
5205 }
5206 }
5207
5208 public Dimension getSize() {
5209 return getBounds().getSize();
5210 }
5211
5212 public void setSize (Dimension d) {
5213 AccessibleContext ac = getCurrentAccessibleContext();
5214 if (ac instanceof AccessibleComponent) {
5215 ((AccessibleComponent) ac).setSize(d);
5216 } else {
5217 Component c = getCurrentComponent();
5218 if (c != null) {
5219 c.setSize(d);
5220 }
5221 }
5222 }
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234 public Accessible getAccessibleAt(Point p) {
5235 AccessibleContext ac = getCurrentAccessibleContext();
5236 if (ac instanceof AccessibleComponent) {
5237 return ((AccessibleComponent) ac).getAccessibleAt(p);
5238 } else {
5239 return null;
5240 }
5241 }
5242
5243 public boolean isFocusTraversable() {
5244 AccessibleContext ac = getCurrentAccessibleContext();
5245 if (ac instanceof AccessibleComponent) {
5246 return ((AccessibleComponent) ac).isFocusTraversable();
5247 } else {
5248 Component c = getCurrentComponent();
5249 if (c != null) {
5250 return c.isFocusTraversable();
5251 } else {
5252 return false;
5253 }
5254 }
5255 }
5256
5257 public void requestFocus() {
5258 AccessibleContext ac = getCurrentAccessibleContext();
5259 if (ac instanceof AccessibleComponent) {
5260 ((AccessibleComponent) ac).requestFocus();
5261 } else {
5262 Component c = getCurrentComponent();
5263 if (c != null) {
5264 c.requestFocus();
5265 }
5266 }
5267 }
5268
5269 public void addFocusListener(FocusListener l) {
5270 AccessibleContext ac = getCurrentAccessibleContext();
5271 if (ac instanceof AccessibleComponent) {
5272 ((AccessibleComponent) ac).addFocusListener(l);
5273 } else {
5274 Component c = getCurrentComponent();
5275 if (c != null) {
5276 c.addFocusListener(l);
5277 }
5278 }
5279 }
5280
5281 public void removeFocusListener(FocusListener l) {
5282 AccessibleContext ac = getCurrentAccessibleContext();
5283 if (ac instanceof AccessibleComponent) {
5284 ((AccessibleComponent) ac).removeFocusListener(l);
5285 } else {
5286 Component c = getCurrentComponent();
5287 if (c != null) {
5288 c.removeFocusListener(l);
5289 }
5290 }
5291 }
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301 public int getAccessibleSelectionCount() {
5302 int count = 0;
5303 int childCount = getAccessibleChildrenCount();
5304 for (int i = 0; i < childCount; i++) {
5305 TreePath childPath = getChildTreePath(i);
5306 if (tree.isPathSelected(childPath)) {
5307 count++;
5308 }
5309 }
5310 return count;
5311 }
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322 public Accessible getAccessibleSelection(int i) {
5323 int childCount = getAccessibleChildrenCount();
5324 if (i < 0 || i >= childCount) {
5325 return null;
5326 }
5327 int count = 0;
5328 for (int j = 0; j < childCount && i >= count; j++) {
5329 TreePath childPath = getChildTreePath(j);
5330 if (tree.isPathSelected(childPath)) {
5331 if (count == i) {
5332 return new AccessibleJTreeNode(tree, childPath, this);
5333 } else {
5334 count++;
5335 }
5336 }
5337 }
5338 return null;
5339 }
5340
5341
5342
5343
5344
5345
5346
5347
5348 public boolean isAccessibleChildSelected(int i) {
5349 int childCount = getAccessibleChildrenCount();
5350 if (i < 0 || i >= childCount) {
5351 return false;
5352 } else {
5353 TreePath childPath = getChildTreePath(i);
5354 return tree.isPathSelected(childPath);
5355 }
5356 }
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367 public void addAccessibleSelection(int i) {
5368 TreeModel model = JTree.this.getModel();
5369 if (model != null) {
5370 if (i >= 0 && i < getAccessibleChildrenCount()) {
5371 TreePath path = getChildTreePath(i);
5372 JTree.this.addSelectionPath(path);
5373 }
5374 }
5375 }
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385 public void removeAccessibleSelection(int i) {
5386 TreeModel model = JTree.this.getModel();
5387 if (model != null) {
5388 if (i >= 0 && i < getAccessibleChildrenCount()) {
5389 TreePath path = getChildTreePath(i);
5390 JTree.this.removeSelectionPath(path);
5391 }
5392 }
5393 }
5394
5395
5396
5397
5398
5399 public void clearAccessibleSelection() {
5400 int childCount = getAccessibleChildrenCount();
5401 for (int i = 0; i < childCount; i++) {
5402 removeAccessibleSelection(i);
5403 }
5404 }
5405
5406
5407
5408
5409
5410 public void selectAllAccessibleSelection() {
5411 TreeModel model = JTree.this.getModel();
5412 if (model != null) {
5413 int childCount = getAccessibleChildrenCount();
5414 TreePath path;
5415 for (int i = 0; i < childCount; i++) {
5416 path = getChildTreePath(i);
5417 JTree.this.addSelectionPath(path);
5418 }
5419 }
5420 }
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432 public int getAccessibleActionCount() {
5433 AccessibleContext ac = getCurrentAccessibleContext();
5434 if (ac != null) {
5435 AccessibleAction aa = ac.getAccessibleAction();
5436 if (aa != null) {
5437 return (aa.getAccessibleActionCount() + (isLeaf ? 0 : 1));
5438 }
5439 }
5440 return isLeaf ? 0 : 1;
5441 }
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452 public String getAccessibleActionDescription(int i) {
5453 if (i < 0 || i >= getAccessibleActionCount()) {
5454 return null;
5455 }
5456 AccessibleContext ac = getCurrentAccessibleContext();
5457 if (i == 0) {
5458
5459 return AccessibleAction.TOGGLE_EXPAND;
5460 } else if (ac != null) {
5461 AccessibleAction aa = ac.getAccessibleAction();
5462 if (aa != null) {
5463 return aa.getAccessibleActionDescription(i - 1);
5464 }
5465 }
5466 return null;
5467 }
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478 public boolean doAccessibleAction(int i) {
5479 if (i < 0 || i >= getAccessibleActionCount()) {
5480 return false;
5481 }
5482 AccessibleContext ac = getCurrentAccessibleContext();
5483 if (i == 0) {
5484 if (JTree.this.isExpanded(path)) {
5485 JTree.this.collapsePath(path);
5486 } else {
5487 JTree.this.expandPath(path);
5488 }
5489 return true;
5490 } else if (ac != null) {
5491 AccessibleAction aa = ac.getAccessibleAction();
5492 if (aa != null) {
5493 return aa.doAccessibleAction(i - 1);
5494 }
5495 }
5496 return false;
5497 }
5498
5499 }
5500
5501 }
5502
5503 }